Chapter 2c: Branch and Jump Details, Subroutines
description
Transcript of Chapter 2c: Branch and Jump Details, Subroutines
Ch2c- 2EE/CS/CPE 3760 - Computer OrganizationSeattle Pacific University
Branch limitations• A conditional branch (BEQ, BNE) uses an I-type
Instruction
• Allows a 16-bit immediate operand
• 216 = 64K Locations is too small• Notice that most branches don’t go very far away
(back to the beginning of a loop, etc.)
• Use PC-relative addresses for branches• Immediate operand is a displacement in 4-byte
words from the next instruction• May be positive (forward branches) or negative
(backwards branches)WARNING: BEQ,BNE example in text canbe misleading. Make a note in text to see slide Ch3c-3.
Ch2c- 3EE/CS/CPE 3760 - Computer OrganizationSeattle Pacific University
Branch example
loop: bgt $t0, $t1, biggerlw $s0, 0($t0)addi $t0, $t0, 1beq $s0, $s1, loop
bigger: move $s2, $t0
8000 loop: slt $1, $8, $98004 bne $1, $0, bigger
5 1 0 +380040 8 9 1 0 428000
35 8 16 080088 8 8 180124 16 17 -580160 8 0 18 0 328020
bigger: + 3 instructions
8020 bigger: add $18, $8, $0
8008 lw $16, 0($8)8012 addi $8, $8, 18016 beq $16, $17, loop
loop: -5 instructions
+3
-5
Branches: offset is in instructions fromthe instruction following the branch
Note: Negative numbers require 2’s complementWARNING: BEQ,BNE example inside text can
be misleading. Make a note in text to see slide Ch3c-3.
Ch2c- 4EE/CS/CPE 3760 - Computer OrganizationSeattle Pacific University
Jump Addressing• Jumps use a J-type instruction and have a 26-bit offset
• A lot more range than 16-bit branches
• Allows a range of 226=64M possibilites
2000: j target
0 2 4 1 0 3220042 5012000
2004: target: add $1, $2, $4501 = 2004/4Example:
• Because the range is so much larger, jumps use absolute addressing
• Absolute addressing just specifies the address of the jump target
• Since all instructions have addresses that are multiples of 4, we only need to put the address divided by 4 in the instruction field• Actual byte address is obtained by multiplying by 4• Allows a range of 64M instructions = 256M bytes
Ch2c- 5EE/CS/CPE 3760 - Computer OrganizationSeattle Pacific University
Jumping based on Registers
• Jumps change the PC to a fixed location
• j OverThere
• Always goes to the same place
JR - Jump RegisterJR - Jump Register
• Is there a way to jump to a place to be determined by the program?
• Put the address to go to in a register• addi $14, $0, 10000
• Jump to the address contained in that register• jr $14
Ch2c- 6EE/CS/CPE 3760 - Computer OrganizationSeattle Pacific University
Lui, Lui• Registers can hold 32 bits, but we can only load in 16-bit
immediate data
• LUI - Load Upper Immediate
• Loads constant into bits 31-16 of register
• Bits 15-0 become zero
lui $8, 0x1A2Bli $8, 0x3C4D
Warning: Don’t use addi for the second instruction – use LI or ORI (sign extension)Warning: Don’t use addi for the second instruction – use LI or ORI (sign extension)
$8: ----31 16 15 0
----1A2B 0000 3C4D
Put the constant with value 0x1A2B3C4D in register $8
We can let the assembler do the work:li $8, 0x1A2B3C4D will be converted to these two instructions
We can let the assembler do the work:li $8, 0x1A2B3C4D will be converted to these two instructions
Ch2c- 7EE/CS/CPE 3760 - Computer OrganizationSeattle Pacific University
Getting around branch limitationsBranches have a limit of +/- 215 instructions - How can we branch further?
Use the larger range of the jump instruction:
1000: beq $s0,$t1,far1004: sub $s2, $v0, $a0…500000: far: add $t1, $t2, $t3
1000: bne $s0,$t1,stay1004: j far1008: stay: sub $s2, $v0, $a0…500000: far: add $t1, $t2, $t3
Can’t branch that far...
Ch2c- 8EE/CS/CPE 3760 - Computer OrganizationSeattle Pacific University
Getting around jump limitations
1000: j reallyfar…834218224: reallyfar: move $t1,$s1
Can’t jump there...
Jumps can address anywhere in the range 0 - 226 words (0 - 228 bytes)
MIPS has an address space of 0 - 232 bytes...
How can we get to programs in the top 15/16 of memory?
1000: lui $t1, 0x31B91004: li $t1, 0x28F01008: jr $t1…834218224: reallyfar: move $t1,$s1
Use 32-bit range of jr
83421822410=31B928F016
Aside: Can we use regular jumps with addresses >= 256MB?
Yes: The high-order four bits are unchanged by the jump instruction
Ch2c- 9EE/CS/CPE 3760 - Computer OrganizationSeattle Pacific University
Subroutines
• Subroutines allow common program portions to be reused
• int CalcInterest(int principle, int time) { ... }
• y = CalcInterest(1000, 10)
• z = CalcInterest(1000, 15)
• When calling a subroutine, you must:
• Set up any parameters
• Save the current position so the program will know where to return to
• Jump to the location of the subroutine
Ch2c- 10EE/CS/CPE 3760 - Computer OrganizationSeattle Pacific University
Jumpin’ and Linkin’• JAL - Jump and Link
• Saves the return address• Write address of next instruction in $31 ($ra)
• Jumps to the address specified and keeps going
100: jal CALC104: sub $4, $4, $2
...342: CALC: add $14,$15,$2346: mult $14, $2
...368: jr $ra
Call the Calc subroutineSave addr. of next instr. in $ra ($31)
Call the Calc subroutineSave addr. of next instr. in $ra ($31)
End of Subroutine.Return to Return Address in $ra
End of Subroutine.Return to Return Address in $ra
$ra
Start of SubroutineStart of Subroutine
104
Ch2c- 11EE/CS/CPE 3760 - Computer OrganizationSeattle Pacific University
Passing Parameters• Most subroutines have parameters to make them
more interesting...
• Z = Addemup(A,B,C)
• In order to pass parameters, we must place the parameters in registers before calling the subroutine
• $a0, $a1, $a2, $a3 used for these ($4 - $7)
• $a0 <-- A, $a1 <--B, $a2 <--C
• Before calling a routine, copy all parameters to the appropriate registers
• Return values are put in $v0, $v1 ($2, $3)
• $v0 <-- Z
• After subroutine finished, copy return values back
Example – Check the weight of various packages; Output message if >600 lbs.Example – Check the weight of various packages; Output message if >600 lbs.
Data: List of 8words containingweights of boxes
Find number ofwords to check andconvert to bytes
Get current weightand put in param.$a0
Check it by callingvalidate procedure
Advance to nextweight and checkif at the end
End Program
Check if weight(in param. $a0)is less than 600
Overweight -Print error msgDone with
subroutine
.data numItems: .word 8 weight: .word 999, 688, 222, 1002, 333, 2, 888, 14000 over: .asciiz " is too heavy.\n"
.text # $t0 is loop counter, $t1 holds ending value main: li $t0,0 # initialize $t0 to 0
lw $t1,numItems($0) # load number of items into $t1 mul $t1,$t1,4 # convert to bytes
check: lw $a0, weight($t0) # load current weight jal validate # check for overweight addi $t0,$t0,4 # increment loop counter bltu $t0,$t1,check # loop back if not done
# exit program li $v0,10 # code for exit syscall # exit program
# validate checks for overweight loads. Weight to check is passed in $a0. validate: blt $a0, 600, OK # check if value is < 600
li $v0,1 # code for print_int syscall # print out result (in $a0) li $v0,4 # code for print_string la $a0,over # point $a0 to over string syscall
OK: jr $ra # return to caller
Ch2c- 13EE/CS/CPE 3760 - Computer OrganizationSeattle Pacific University
A Stack
2008$sp
To push a new value on: Decrement $sp (by 4) and write to memory
To push a new value on: Decrement $sp (by 4) and write to memory
addi $sp, $sp, -4 # decrement stack for pushsw $t0, 0($sp) # push reg. $t0 onto stack
lw $t0, 0($sp) # pop stack into reg. $t0 addi $sp, $sp, 4 # increment stack for pop
Push $t0 (111)Push $t0 (111)
Pop into $t0Pop into $t0
$sp($29) points to the top of the stack
$sp($29) points to the top of the stack H
ighe
r M
emor
y A
ddre
sses
13432
9288322212
23232212
...
23876
2032202820242020201620122008
...
20042000
......Memory
Top of Stack
Free Memory
Values already onstack
lw $t0, 0($sp) # read the top of the stack Read TopRead Top
2004
1112008
$t0:111
Ch2c- 14EE/CS/CPE 3760 - Computer OrganizationSeattle Pacific University
A bit of a problem
• Some wise guy (or gal) is going to decide to call a procedure from another procedure
procA: li $a1,1jal procBmove $t0,$v0jr $ra
...jal procAaddi $3,$4,5...
$ra:
Somehow, we’ve gotto save the old R.A.for future use.
Somehow, we’ve gotto save the old R.A.for future use.
• When we JAL the second time, we overwrite the value in $ra
• We’re lost now...
procB: move $t1,$a1jr $ra
Ch2c- 15EE/CS/CPE 3760 - Computer OrganizationSeattle Pacific University
Stacking things up
• If we’re going to a new subroutine, save the old $ra value on the stack first
• This is the primary reason for the system stack
Adjust the SP first
Now, store old RA on stack
Restore the RA
Re-adjust the SP 20002004200820122016
25342221965
2$sp 2008
16308
2004 20042008
Call the subroutine
$ra 16308812416308
• Push the old RA on the stack...
8112 addi $sp, $sp, -4
8116 sw $ra, 0($sp)
8120 jal B
8124 lw $ra, 0($sp)
8128 addi $sp, $sp, 4
Modify validate subr. to also check if the weight is odd
Modify validate subr. to also check if the weight is odd
check if weight is > 600 - print error if it isget ready to call checkOdd by pushing old $ra on the stack
call checkOdd (parampassed in $a0)
checks if odd, returns value in $v0
restore old $racheck result, print error msg if not
end subr. by going to $ra
# validate checks for overweight loads. Weight to check is passed in $a0.validate: blt $a0, 600, WeightOK # if value < 600 then OK
# print out an error message<code deleted to save space on slide>
WeightOK: addi $sp,$sp,-4 # decrement stack pointer by 4sw $ra, 0($sp) # push RA on stack
jal checkOdd # now check if odd (return value in $v0)
lw $ra, 0($sp) # pop RA off stackaddi $sp, $sp, 4 # increment stack pointer by 4
beqz $v0, OK # if weight is even, OK# print out an error message <code deleted to save space on slide>
OK: jr $ra # return to caller
# checkOdd checks if weight is Odd. Weight passed in $a0. $v0 is 0 if even, 1 if odd
checkOdd: rem $v0, $a0, 2 # $v0 <-- 1 if weight is odd, 0 if even jr $ra # return to caller
Ch2c- 17EE/CS/CPE 3760 - Computer OrganizationSeattle Pacific University
Extra parameters
• Your overachiever friend has a procedure with 8 parameters and 3 return values
• Won’t work: Only get 4 params, and 2 return values
• Pass the extra parameters by placing them on the stack before calling the subroutine
• Local variables
• Local variables for procedures need space allocated each time the procedure is called
• Use the stack for this:addi $sp, $sp, -8 #allocate space for 2 words• De-allocate memory before returning from subroutine
Ch2c- 18EE/CS/CPE 3760 - Computer OrganizationSeattle Pacific University
Clobbering things• Let’s say that you’re using registers $t3 and $s2 in
your program
• You call a procedure
• What if the procedure overwrites $t3 or $s2• You’ve been clobbered!
• Somebody’s got to save the registers and restore them when beginning and ending the procedure call
• Caller saved: Calling program responsible for saving registers. Procedure may use any at will.
• $t0 - $t9• Callee saved: Called program must save and restore
any registers it uses.• $s0 - $s7
Ch2c- 19EE/CS/CPE 3760 - Computer OrganizationSeattle Pacific University
Thoughts about MIPS programming
• Write the program in C/C++ first
• Break it into procedures as appropriate
• Convert the program to assembly language
• Start out simple
• Get basic parts working before adding error checking, etc.
• Don’t forget: Words are 4 bytes
• Use pseudoinstructions when applicable