Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

MIPS_primery_zadach / dandamudi05gtr guide risc processors programmers engineers

.pdf
Скачиваний:
81
Добавлен:
11.05.2015
Размер:
1.39 Mб
Скачать

246

Guide to RISC Processors

rizes the comparison instructions provided by the assembler. Notice that all comparison instructions in Table 14.1 are pseudoinstructions. For example, the pseudoinstruction

seq $a0,$a1,$a2

is translated as

beq $6,$5,skip1 ori $4,$0,0

beq $0,$0,skip2 skip1:

ori $4,$0,1 skip2:

. . .

Note that $a0, $a1, and $a2 represent registers $4, $5, and $6, respectively. The branch instructions are discussed next.

Unconditional Branch Instructions

Unconditional transfer of control is implemented by jump and branch instructions. Let us first look at the basic jump instruction. The jump instruction

j target

transfers control to the target address. As discussed before, this is a direct jump instruction in which the target address is given as part of the instruction. In the MIPS32 architecture, the control is transferred to target after executing the delay slot instruction. However, see the following SPIM note.

SPIM note

Because SPIM does not simulate delayed branch, it does not exe-

cute the delay slot instruction.

 

 

 

There are other types of jump instructions that are useful as procedure calls. We have already discussed some of these instructions in Chapter 11. For example, we use the jal instruction to invoke a procedure. Similarly, the jr instruction is used to return from a procedure.

Branch instructions provide a more flexible test and jump execution. MIPS supports several branch instructions. We describe some of these instructions in this section.

The unconditional branch instruction

btarget

transfers control to target unconditionally. Semantically, it is very similar to the jump instruction. The main difference is that the b instruction uses a 16-bit relative address

Chapter 14 Conditional Execution

247

whereas the j instruction uses a 26-bit absolute address. Thus, the jump instruction has a larger range than the branch instruction. But the branch is more convenient because it uses relative address.

An Example To illustate the difference between jump and branch instructions, let us look at the following code fragement.

 

loop_back:

 

[0x00400048]

addu

$t0,$t0,$t1

[0x0040004c]

j

loop_back

The numbers in the square brackets are the addresses of the instructions. For example, the addu instruction is at address 0x00400048. The SPIM assembler translates the jump (j) instruction in this code as

j 0x00400048

by replacing the label loop_back by its address 0x00400048. As you can see from this example, the absolute value is used to specify the target address. However, as we have seen in Chapter 11, the instruction encoding is slightly different. The instruction encoding follows the explanation given in the example on page 186. If you have read that explanation on how the jal instruction is encoded, you will see that the j instruction follows similar encoding.

As in the jal instruction, this instruction uses the J-type encoding shown in Figure 4.2 on page 52. This jump instruction is encoded as 0x08100012. The target address is specified using 26 bits as shown below:

Opcode

Offset

0000 10 00 0001 0000 0000 0000 0001 0010

Because all instructions are aligned on word boundaries, the least significant 2 bits are always zero. As a result, these 2 bits are not explicitly stored in the instruction. By appending these 2 zeros, we get the 28-bit offset value as 0x0400048. By adding the most significant 4 bits from the PC, we get the target address as 0x00400048, which is the address of the addu instruction at loop_back.

Now we replace the jump instruction by the branch instruction as shown below:

 

loop_back:

 

[0x00400048]

addu

$t0,$t0,$t1

[0x0040004c]

b

loop_back

The unconditional branch instruction (b) is encoded as

bgez $0,-4

248

Guide to RISC Processors

This example gives the following information about the encoding of the b instruction:

Because the branch instruction is actually a pseudoinstruction, it is encoded using the conditional branch instruction bgez. How can this instruction implement an unconditional branch? Well, we compare register $0 to zero and jump to target if the register has a value greater than or equal to zero. Register $0 is hardwired to zero, therefore the test is always true, causing the jump to always take place.

The offset used is a PC-relative value, not the absolute value as in the j instruction. In our example, the relative offset is 4.

Conditional Branch Instructions

Now we look at the conditional branch instructions. These instructions compare the contents of two registers and jump to the target if the specified condition is true. For example, the branch instruction

beq Rsrc1,Rsrc2,target

compares the contents of Rsrc1 and Rsrc2 and transfers control to target if they are equal.

Branch instructions to test “less than” and “greater than” are also supported. As an example, the instruction

bgt Rsrc1,Rsrc2,target

branches to the target location when the contents of Rsrc1 are greater than Rsrc2. When comparing, the contents of Rsrc1 and Rsrc2 are treated as signed numbers. For unsigned numbers, we have to use the bgtu instruction.

Branch instructions to test combinations such as “greater than or equal to” are also available. Table 14.2 summarizes some of the branch instructions provided by the MIPS assembler.

Very often, we need to compare a value with zero and transfer control to the target based on this comparison. This is often the case in constructing loops. For example, look at the code given at the beginning of this chapter. For this reason, MIPS supports conditional branch instructions that compare with zero. To illustrate the format of these instructions, we use the beqz instruction. The format is

beqz Rsrc,target

This instruction transfers control to target if the value of Rsrc is equal to zero. Table 14.3 summarizes these instructions.

Chapter 14 Conditional Execution

249

Table 14.2 MIPS branch instructions (based on register comparison)

Instruction

Description

b

target

Branches unconditionally to target.

beq

Rsrc1,Rsrc2,target

Branches to target if the contents of Rsrc1 and

 

 

Rsrc2 are equal.

bne

Rsrc1,Rsrc2,target

Branches to target if the contents of Rsrc1 and

 

 

Rsrc2 are not equal.

blt

Rsrc1,Rsrc2,target

Branches to target if the value of Rsrc1 is less

 

 

than the value of Rsrc2. The source operands are

 

 

considered as signed numbers.

bltu

Rsrc1,Rsrc2,target

Same as blt except that the source operands are

 

 

treated as unsigned numbers.

bgt

Rsrc1,Rsrc2,target

Branches to target if the value of Rsrc1 is greater

 

 

than the value of Rsrc2. The source operands are

 

 

treated as signed numbers.

bgtu

Rsrc1,Rsrc2,target

Same as bgt except that the source operands are

 

 

treated as unsigned numbers.

ble

Rsrc1,Rsrc2,target

Branches to target if the value of Rsrc1 is less

 

 

than or equal to the value of Rsrc2. The source

 

 

operands are treated as signed numbers.

bleu

Rsrc1,Rsrc2,target

Same as ble except that the source operands are

 

 

treated as unsigned numbers.

bge

Rsrc1,Rsrc2,target

Branches to target if the value of Rsrc1 is greater

 

 

than or equal to the value of Rsrc2. The source

 

 

operands are treated as signed numbers.

bgeu

Rsrc1,Rsrc2,target

Same as bge except that the source operands are con-

 

 

sidered as unsigned numbers.

 

 

 

Our First Program

As our first example of the chapter, we look at counting the number of uppercase letters in a given string. The program listing is given in Program 14.1. The main program prompts the user for a string and passes it on to the count procedure via the $a0 register. The count procedure returns the uppercase count in $v0. The procedure follows the algorithm given below:

250

Guide to RISC Processors

Table 14.3 MIPS branch instructions (based on comparison to zero)

Instruction

Description

beqz

Rsrc,target

Branches to target if the value of Rsrc is equal to

 

 

zero.

bnez

Rsrc,target

Branches to target if the value of Rsrc is not equal

 

 

to zero.

bltz

Rsrc,target

Branches to target if the value of Rsrc is less than

 

 

zero.

bgtz

Rsrc,target

Branches to target if the value of Rsrc is greater

 

 

than zero.

blez

Rsrc,target

Branches to target if the value of Rsrc is less than

 

 

or equal to zero.

bgez

Rsrc,target

Branches to target if the value of Rsrc is greater

 

 

than or equal to zero.

 

 

 

count(string) uppercase_count := 0 i := 0

while (string[i] =NULL)

if ((string[i] A) AND (string[i] Z)) uppercase_count := uppercase_count + 1

end if

i := i + 1 end while

return (uppercase_count) end count

The if condition is tested on lines 63 and 64. If the condition is true, the uppercase count (in $v0) is incremented on line 65. The count loop index (in $t0) is incremented on line 67. The while loop condition is tested on line 62. If the loop condition is not true, the loop is terminated by the beqz instruction on line 62.

Program 14.1 A program to count the number of uppercase letters in a string

1: # Counts the uppercase letters

UPPER_COUNT.ASM

2:#

3:# Objective: Counts uppercase letters in a string.

4:# Input: Requests a string from the user.

Chapter 14 Conditional Execution

251

5:# Output: Outputs the uppercase letter count.

6:#

7:# $a0 - string pointer

8:# $v0 - returns the uppercase letter count

9:#

10:################### Data segment #######################

11:.data

12:prompt:

13:

.asciiz

"Please enter a string: \n"

14:out_msg:

15:

.asciiz

"The number of uppercase letters is: "

16:newline:

17: .asciiz "\n"

18:in_string:

19:

.space

31

20:

 

 

21:################### Code segment #######################

22:.text

23:.globl main

24:main:

25:

la

$a0,prompt

# prompt user for input

26:li $v0,4

27:syscall

29:

la

$a0,in_string

#

read input string

30:

li

$a1,31

#

buffer length in $a1

31:li $v0,8

32:syscall

34:

la

$a0,in_string

# call the count proc.

35:

jal

count

 

 

36:

move

$t0,$v0

#

count is in $v0

37:

 

 

 

 

38:

la

$a0,out_msg

#

write output message

39:li $v0,4

40:syscall

42:

move $a0,$t0

# output the count

43:li $v0,1

44:syscall

46:

la

$a0,newline

# write newline

47:li $v0,4

48:syscall

50:

li

$v0,10

# exit

51:syscall

252

Guide to RISC Processors

52:

53:#-----------------------------------------------------

54:# COUNT receives a pointer to a string in $a0 and

55:# returns the number of uppercase letters in $v0.

56:# $t0 - temporary

57:#-----------------------------------------------------

58:count:

59:

li

$v0,0

# count = 0

60:count_loop:

61:lbu $t0,($a0)

62:

beqz $t0,count_done

# if NULL, we are done

63:bgtu $t0,’Z’,skip_count

64:bltu $t0,’A’,skip_count

65:

addu $v0,$v0,1

# update count

66:skip_count:

67:addu $a0,$a0,1

68: b count_loop

69:count_done:

70:jr $ra

Illustrative Examples

We give two examples to further illustrate the instructions discussed in this chapter.

Example 14.1 Sorting of an integer array using selection sort.

The main program, shown in Program 14.2, prompts the user for the array values. The read loop on lines 33–39 reads the values entered by the user. This loop is terminated when a zero is entered. This is not a safe loop as it is possible to exceed the array bounds (which in our example can take 50 elements). You can make this loop safe by adding another termination condition that takes care of the array boundary.

The main program copies the array pointer into $a0 (line 42) and its size in $a1 (line 43 and 44). Notice that we use the shift right instruction (srl) on line 44 to divide the byte count by 4 to get the array size. The selection sort procedure is invoked on line 45. After the array has been sorted, the main program displays the sorted array using the loop on lines 52–61.

Program 14.2 Selection sort program

1: # Selection sort

SEL_SORT.ASM

2:#

3:# Objective: Sorts an array using selection sort.

4:# Input: Requests integers from the user;

Chapter 14

Conditional Execution

253

5: #

terminated by entering a zero.

 

6:# Output: Outputs the sorted integer array.

7:#

8:# $a0 - array pointer

9:# $a1 - array size

10:#

11:#################### Data segment ########################

12:.data

13:prompt:

14:

.ascii

"Please enter integers (at least two).\n"

15:

.asciiz

"Entering zero terminates the input.\n"

16:output_msg:

17:

.asciiz

"The sorted array is:\n"

18:newline:

19: .asciiz "\n"

20:.align 2

21:array:

22:

.space

200

# space for 50 integers

23:

 

 

 

24:#################### Code segment ########################

25:.text

26:.globl main

27:main:

28:

la

$a0,prompt

# prompt user for input

29:li $v0,4

30:syscall

32:la $t0,array

33:read_more:

34:

li

$v0,5

# read a number

35:syscall

36:

sw

$v0,($t0)

# store it in the array

37:beqz $v0,exit_read

38:addu $t0,$t0,4

39: b read_more

40:exit_read:

41:# prepare arguments for procedure call

42:

la

$a0,array

# $a0 = array pointer

43:subu $a1,$t0,$a0 # $a1 = array size in bytes

44:

srl

$a1,$a1,2

#

$a1 = $a1/4

45:

jal

sel_sort

 

 

46:

 

 

 

 

47:

la

$a0,output_msg

#

write output message

48:li $v0,4

49:syscall

51: la $t0,array

254

Guide to RISC Processors

52:write_more:

53:

lw

$a0,($t0)

# output sorted array

54:beqz $a0,exit_write

55:li $v0,1

56:syscall

57:

la

$a0,newline

# write newline

58:li $v0,4

59:syscall

60:addu $t0,$t0,4

61:

b

write_more

 

62:

exit_write:

 

 

63:

 

 

 

64:

li

$v0,10

# exit

65:

syscall

 

66:

 

 

 

67:#--------------------------------------------------------

68:# SEL_SORT receives a pointer to the array in $a0 and

69:# its size in $a1. It sorts the array in ascending order

70:# using the selection sort algorithm.

71:# $t1 - array[j] pointer

72:# $t2 - min_value

73:# $t3 - array[min_position] pointer

74:# $t4 - used as a temporary

75:# $a0 - array[position] pointer

76:# $a1 - array[size-1] pointer

77:#--------------------------------------------------------

78:sel_sort:

79:# computes array[size-1] pointer (i.e., &A[size-1])

80:subu $a1,$a1,1

81:sll $a1,$a1,2

82:addu $a1,$a1,$a0

83:

84:########### outer for loop ############

85:outer_for:

86:

lw

$t2,($a0)

#

min_value = A[position]

87:

move

$t3,$a0

#

&A[min_position] = &A[position]

88:

 

 

 

 

89:# inner for loop

90:

addu $t1,$a0,4

# &A[j] = &A[position+1]

91:inner_for:

92:

lw

$t4,($t1)

# 1st if condition

93:

bgeu

$t4,$t2,skip_1st_if

#

94:

 

 

 

95:# 1st if statement

96:

move

$t2,$t4

# min_value = A[j]

97:

move

$t3,$t1

# &A[min_pos] = &A[j]

98:

# end

of 1st if statement

Chapter 14 Conditional Execution

255

99:

100:skip_1st_if:

101:

addu $t1,$t1,4

# $t1 = &A[j+1]

102:bleu $t1,$a1,inner_for

103:# end of inner for loop

105:beq $a0,$t3,skip_2nd_if # 2nd if condition

106:second_if:

107:# 2nd if statement

108:lw $t4,($a0)

109:sw $t4,($t3)

110:sw $t2,($a0)

111:# end of 2nd if statement

112:

113:skip_2nd_if:

114:

addu $a0,$a0,4

# $a0 = &A[position+1]

115:bltu $a0,$a1,outer_for

116:# end of outer for loop

118: jr $ra

The sort procedure receives a pointer to the array to be sorted in $a0 and its size in $a1. It uses the selection sort algorithm to sort the array in ascending order. The basic idea is as follows.

1.Search the array for the smallest element;

2.Move the smallest element to the first position by exchanging values of the first and smallest element positions;

3.Search the array for the smallest element from the second position of the array;

4.Move this element to the second position by exchanging values as in Step 2;

5.Continue this process until the array is sorted.

The selection sort procedure implements the following pseudocode.

selection_sort (array, size) for (position = 0 to size2)

min_value := array[position] min_position := position

for (j = position+1 to size1) if (array[j] < min_value) then

min_value := array[j] min_position := j

end if

Соседние файлы в папке MIPS_primery_zadach