1 / 19

Chapter 2c: Branch and Jump Details, Subroutines

Chapter 2c: Branch and Jump Details, Subroutines. Branch limitations. A conditional branch (BEQ, BNE) uses an I-type Instruction Allows a 16-bit immediate operand 2 16 = 64K Locations is too small. Notice that most branches don’t go very far away (back to the beginning of a loop, etc.)

roch
Télécharger la présentation

Chapter 2c: Branch and Jump Details, Subroutines

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Chapter 2c: Branch and Jump Details, Subroutines

  2. 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.) • UsePC-relativeaddresses 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.

  3. 8000 loop: slt $1, $8, $9 8004 bne $1, $0, bigger 8000 0 8 9 1 0 42 8004 5 1 0 +3 8008 35 8 16 0 8012 8 8 8 1 8016 4 16 17 -5 8020 0 8 0 18 0 32 Branches: offset is in instructions fromthe instruction following the branch Branch example loop: -5 instructions +3 loop: bgt $t0, $t1, bigger lw $s0, 0($t0) addi $t0, $t0, 1 beq $s0, $s1, loop bigger: move $s2, $t0 8008 lw $16, 0($8) 8012 addi $8, $8, 1 -5 8016 beq $16, $17, loop 8020 bigger: add $18, $8, $0 bigger: + 3 instructions Note: Negative numbers require 2’s complement WARNING: BEQ,BNE example inside text canbe misleading. Make a note in text to see slide Ch3c-3.

  4. 2004 2000 0 2 4 1 0 32 2 501 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 • 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 Example: 2000: j target 501 = 2004/4 2004: target: add $1, $2, $4

  5. Jumping based on Registers • Jumps change the PC to a fixed location • j OverThere • Always goes to the same place • 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 JR - Jump Register

  6. ---- ---- $8: 31 16 15 0 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 Put the constant with value 0x1A2B3C4D in register $8 Warning: Don’t use addi for the second instruction – use LI or ORI (sign extension) lui $8, 0x1A2B li $8, 0x3C4D We can let the assembler do the work:li $8, 0x1A2B3C4D will be converted to these two instructions 1A2B 0000 3C4D

  7. Getting around branch limitations Branches have a limit of +/- 215 instructions - How can we branch further? 1000: bne $s0,$t1,stay 1004: j far 1008: stay: sub $s2, $v0, $a0 … 500000: far: add $t1, $t2, $t3 1000: beq $s0,$t1,far 1004: sub $s2, $v0, $a0… 500000: far: add $t1, $t2, $t3 Can’t branch that far... Use the larger range of the jump instruction:

  8. Getting around jump limitations 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? Use 32-bit range of jr 1000: lui $t1, 0x31B9 1004: li $t1, 0x28F0 1008: jr $t1 … 834218224: reallyfar: move $t1,$s1 1000: j reallyfar… 834218224: reallyfar: move $t1,$s1 Can’t jump there... 83421822410=31B928F016 Aside: Can we use regular jumps with addresses >= 256MB? Yes: The high-order four bits are unchanged by the jump instruction

  9. 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

  10. 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 Call the Calc subroutine Save addr. of next instr. in $ra ($31) 100: jal CALC 104: sub $4, $4, $2 ... 342: CALC: add $14,$15,$2 346: mult $14, $2 ... 368: jr $ra 104 $ra Start of Subroutine End of Subroutine. Return to ReturnAddress in $ra

  11. 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

  12. Example – Check the weight of various packages; Output message if >600 lbs. .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 bytescheck: 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 syscallOK: jr $ra # return to caller 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 msg Done withsubroutine

  13. Higher Memory Addresses Memory A Stack Free Memory ... ... 2000 876 Top of Stack 2004 23 111 2008 2008 2212 2004 Values already onstack 2012 2323 $sp 2008 2016 12 2020 22 $sp($29) points to the top of the stack 2024 928832 To push a new value on: Decrement $sp (by 4) and write to memory 2028 32 2032 134 ... ... lw $t0, 0($sp) # read the top of the stack Read Top addi $sp, $sp, -4 # decrement stack for push sw $t0, 0($sp) # push reg. $t0 onto stack $t0:111 Push $t0 (111) lw $t0, 0($sp) # pop stack into reg. $t0 addi $sp, $sp, 4 # increment stack for pop Pop into $t0

  14. A bit of a problem • Some wise guy (or gal) is going to decide to call a procedure from another procedure • When we JAL the second time, we overwrite the value in $ra • We’re lost now... Somehow, we’ve got to save the old R.A. for future use. ... jal procA addi $3,$4,5 ... procA: li $a1,1 jal procB move $t0,$v0 jr $ra procB: move $t1,$a1 jr $ra $ra:

  15. 2000 25 2004 342 2008 221 2012 965 2016 2 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 • 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 Adjust the SP first Now, store old RA on stack Call the subroutine Restore the RA Re-adjust the SP 16308 16308 8124 2008 $ra 2004 16308 $sp 2008 2004

  16. Modify validate subr. to also check if the weight is odd # 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 4 sw $ra, 0($sp) # push RA on stack jal checkOdd # now check if odd (return value in $v0) lw $ra, 0($sp) # pop RA off stack addi $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 check if weight is > 600 - print error if it is get ready to call checkOdd by pushing old $ra on the stack call checkOdd (parampassed in $a0) check result, print error msg if not restore old $ra end subr. by going to $ra checks if odd, returns value in $v0

  17. 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

  18. 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

  19. 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

More Related