1 / 39

CS 230: Computer Organization and Assembly Language

CS 230: Computer Organization and Assembly Language. Aviral Shrivastava. Department of Computer Science and Engineering School of Computing and Informatics Arizona State University. Slides courtesy: Prof. Yann Hang Lee, ASU, Prof. Mary Jane Irwin, PSU, Ande Carle, UCB. Announcements. Quiz 1

reid
Download Presentation

CS 230: Computer Organization and Assembly Language

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. CS 230: Computer Organization and Assembly Language Aviral Shrivastava Department of Computer Science and Engineering School of Computing and Informatics Arizona State University Slides courtesy: Prof. Yann Hang Lee, ASU, Prof. Mary Jane Irwin, PSU, Ande Carle, UCB

  2. Announcements • Quiz 1 • Collect your answer sheet from TA • Grades are online • Grade distribution is online (Avg. 53 points) • Project 1 • Grades online • Quiz 2 • Complete Chapter 2 • MIPS Assembly Language Programming, including function calls • Thursday, Sept 24, 2009 • Project 2 • MIPS Assembly Language Programming, including function calls • Will be posted tonight, will be due in a week • Will take a day or two to program

  3. What have we learned • So far • Write any program in MIPS • Today • More Examples of Function Calls

  4. Below the Program • High-level language program (in C) • swap (int v[], int k) • . . . • Assembly language program (for MIPS) • swap: sll $2, $5, 2 • add $2, $4, $2 • lw $15, 0($2) • lw $16, 4($2) • sw $16, 0($2) • sw $15, 4($2) • jr $31 • Machine (object) code (for MIPS) • 000000 00000 00101 0001000010000000 • 000000 00100 00010 0001000000100000 • 100011 00010 01111 0000000000000000 • 100011 00010 10000 0000000000000100 • 101011 00010 10000 0000000000000000 • 101011 00010 01111 0000000000000100 • 000000 11111 00000 0000000000001000 C - Compiler Assembler

  5. MIPS Instructions, so far

  6. MIPS Organization Processor Memory Register File 1…1100 src1 addr src1 data 5 32 src2 addr 32 registers ($zero - $ra) 5 dst addr read/write addr 5 src2 data write data 32 230 words 32 32 32 bits br offset read data 32 Add PC 32 32 32 32 Add 32 4 write data 0…1100 Fetch PC = PC+4 32 0…1000 32 4 5 6 7 0…0100 32 ALU 0 1 2 3 0…0000 Exec Decode 32 word address (binary) 32 bits 32 byte address (big Endian)

  7. MIPS R3000 ISA Registers R0 - R31 • Instruction Categories • Arithmetic • Load/Store • Jump and Branch • Floating Point • coprocessor • Memory Management • Special PC HI LO • 3 Instruction Formats: all 32 bits wide 6 bits 5 bits 5 bits 5 bits 5 bits 6 bits R Format rs rt OP rd sa funct 6 bits 5 bits 5 bits 16 bits I Format rs OP rt immediate 6 bits 26 bits J Format jump target OP

  8. Programming Styles • Procedures (subroutines) allow the programmer to structure programs making them • easier to understand and debug and • allowing code to be reused • Procedures allow the programmer to concentrate on one portion of the code at a time • parameters act as barriers between the procedure and the rest of the program and data, allowing the procedure to be passed values (arguments) and to return values (results)

  9. Requirements for Functions • Pass arguments to the function • $a0, $a1, $a2, $a3 • Get results from the function • $v0, $v1 • Can call from anywhere • jal • Can always return back • jr • Nested and Recursive Functions • Save $ra on stack • Saving and Restoring Registers • Functions with more than 4 parameters

  10. Steps for Making a Function Call 1) Save necessary values onto stack 2) Assign argument(s), if any 3) jal call 4) Restore values from stack

  11. Example Function • int sumSquare(int x, int y) { return mult(x,x)+ y; • } sumSquare: addi $sp,$sp,-8 # space on stack sw $ra, 4($sp) # save ret addr sw $a1, 0($sp) # save y “push” add $a1,$a0,$zero # mult(x,x) jal mult # call mult lw $a1, 0($sp) # restore y add $v0,$v0,$a1 # mult()+y lw $ra, 4($sp) # get ret addr addi $sp,$sp,8 # restore stack jr $ra mult: ... “pop”

  12. Rules for Function Calls • Called with a jalinstruction, returns with a jr $ra • Accepts up to 4 arguments in $a0, $a1, $a2 and $a3 • Return value is always in $v0 (and if necessary in $v1) • Must follow register conventions • even in functions that only you will call!

  13. Other Registers • $at: may be used by the assembler at any time; unsafe to use • $k0-$k1: may be used by the OS at any time; unsafe to use • $gp, $fp: don’t worry about them • Feel free to read up on $gpand $fpin Appendix A, but you can write perfectly good MIPS code without them.

  14. Basic Structure of a Function Prologue entry_label:addi $sp,$sp, -framesizesw $ra, framesize-4($sp) # save $rasave other regs if need be ... restore other regs if need belw $ra, framesize-4($sp) # restore $raaddi $sp,$sp, framesizejr $ra ra Body (call other functions…) memory Epilogue

  15. Register Conventions • CalleR: the calling function • CalleE: the function being called • When callee returns from executing, the caller needs to know which registers may have changed and which are guaranteed to be unchanged. • Register Conventions: A set of generally accepted rules as to which registers will be unchanged after a procedure call (jal) and which may be changed.

  16. Register Conventions • None guaranteed  inefficient • Caller will be saving lots of regs that callee doesn’t use! • All guaranteed  inefficient • Callee will be saving lots of regs that caller doesn’t use! • Register convention: A balance between the two.

  17. Register Conventions – Saved Registers • $0: No Change. Always 0. • $s0-$s7: Restore if you change. Very important, that’s why they’re called saved registers. If the callee changes these in any way, it must restore the original values before returning. • $sp: Restore if you change. The stack pointer must point to the same place before and after the jal call, or else the caller won’t be able to restore values from the stack. • HINT -- All saved registers start with S!

  18. Register Conventions – Volatile Registers • $ra: Can Change. The jal call itself will change this register. Caller needs to save on stack if nested call. • $v0-$v1: Can Change. These will contain the new returned values. • $a0-$a3:Can change. These are volatile argument registers. Caller needs to save if they’ll need them after the call. • $t0-$t9: Can change. That’s why they’re called temporary: any procedure may change them at any time. Caller needs to save if they’ll need them afterwards.

  19. MIPS Register Convention

  20. Register Conventions • What do these conventions mean? • If function R calls function E, then function R must save any temporary registers that it may be using onto the stack before making a jal call. • Function E must save any S (saved) registers it intends to use before garbling up their values • Remember: Caller/callee need to save only temporary/saved registers they are using, not all registers.

  21. Requirements for Functions • Pass arguments to the function • $a0, $a1, $a2, $a3 • Get results from the function • $v0, $v1 • Can call from anywhere • jal • Can always return back • jr • Nested and Recursive Functions • Save $ra on stack • Saving and Restoring Registers • Register Conventions • Functions with more than 4 parameters • Pass them on the stack

  22. Nested Procedures • Leaf procedures do not call other procedures. • What happens to return addresses with nested procedures? int rt_1 (int i) { if (i == 0) return 0; else return rt_2(i-1); } caller: jal rt_1 next: . . . rt_1: bne $a0, $zero, to_2 add $v0, $zero, $zero jr $ra to_2: addi $a0, $a0, -1 jal rt_2 jr $ra rt_2: . . .

  23. Nested Procedures Outcome int rt_1 (int i) { if (i == 0) return 0; else return rt_2(i-1); } caller: jal rt_1next: . . . rt_1: bne $a0, $zero, to_2 add $v0, $zero, $zero jr $ra to_2: addi $a0, $a0, -1 jal rt_2 jr $ra rt_2: . . . • On the call to rt_1, the return address (next in the caller routine) gets stored in $ra. What happens to the value in $ra (when i != 0) when rt_1 makes a call to rt_2?

  24. Saving the Return Address, Part 1 int rt_1 (inti) { if (i == 0) return 0; else return rt_2(i-1); } high addr Nested procedures (i passed in $a0, return value in $v0) rt_1: bne $a0, $zero, to_2 add $v0, $zero, $zero jr $ra to_2: addi $sp, $sp, -8 sw $ra, 4($sp) sw $a0, 0($sp) addi $a0, $a0, -1 jal rt_2 bk_2: lw $a0, 0($sp) lw $ra, 4($sp) addi $sp, $sp, 8 jr $ra $sp old TOS caller rt addr $a0 value low addr caller rt addr bk_2 $ra $a0 value $a0 $a0 value - 1 • Save the return address (and arguments) on the stack $rt_2 $a0 value

  25. Compiling a Recursive Procedure • Calculating factorial: int fact (int n) { if (n < 1) return 1; else return (n * fact (n-1)); } • Recursive procedure (one that calls itself!) fact (0) = 1 fact (1) = 1 * 1 = 1 fact (2) = 2 * 1 * 1 = 2 fact (3) = 3 * 2 * 1 * 1 = 6 fact (4) = 4 * 3 * 2 * 1 * 1 = 24 . . . • Assume n is passed in $a0; result returned in $v0

  26. Compiling a Recursive Procedure int fact (int n) { if (n < 1) return 1; else return (n * fact (n-1)); } fact: addi $sp, $sp, -8 #adjust stack pointer sw $ra, 4($sp) #save return address sw $a0, 0($sp) #save argument n slt $t0, $a0, 1 #test for n < 1 beq $t0, $zero, L1 #if n >=1, go to L1 addi $v0, $zero, 1 #else return 1 in $v0 addi $sp, $sp, 8 #adjust stack pointer jr $ra #return to caller L1: addi $a0, $a0, -1 #n >=1, so decrement n jal fact #call fact with (n-1) #this is where fact returns bk_f: lw $a0, 0($sp) #restore argument n lw $ra, 4($sp) #restore return address addi $sp, $sp, 8 #adjust stack pointer mul $v0, $a0, $v0 #$v0 = n * fact(n-1) jr $ra #return to caller

  27. A Look at the Stack for $a0 = 2 int fact (int n) { if (n < 1) return 1; else return (n * fact (n-1)); } old TOS  $sp caller rt addr fact: addi $sp, $sp, -8 sw $ra, 4($sp) sw $a0, 0($sp) slt $t0, $a0, 1 beq $t0, $zero, L1 addi $v0, $zero, 1 addi $sp, $sp, 8 jr $ra L1: addi $a0, $a0, -1 jal fact bk_f: lw $a0, 0($sp) lw $ra, 4($sp) addi $sp, $sp, 8 mul $v0, $a0, $v0 jr $ra $a0 = 2 caller rt addr bk_f $ra 1 2 $a0 $v0

  28. A Look at the Stack for $a0 = 2 int fact (int n) { if (n < 1) return 1; else return (n * fact (n-1)); } old TOS caller rt addr • Stack state after execution of first encounter with the jal instruction (second call to fact routine with $a0 now holding 1) • saved return address to caller routine (i.e., location in the main routine where first call to fact is made) on the stack • saved original value of $a0 on the stack  $sp $a0 = 2 bk_f $ra 1 $a0 $v0

  29. A Look at the Stack for $a0 = 2 int fact (int n) { if (n < 1) return 1; else return (n * fact (n-1)); } old TOS caller rt addr fact: addi $sp, $sp, -8 sw $ra, 4($sp) sw $a0, 0($sp) slt $t0, $a0, 1 beq $t0, $zero, L1 addi $v0, $zero, 1 addi $sp, $sp, 8 jr $ra L1: addi $a0, $a0, -1 jal fact bk_f: lw $a0, 0($sp) lw $ra, 4($sp) addi $sp, $sp, 8 mul $v0, $a0, $v0 jr $ra  $sp $a0 = 2 bk_f $a0 = 1 bk_f $ra 1 0 $a0 $v0

  30. A Look at the Stack for $a0 = 2 int fact (int n) { if (n < 1) return 1; else return (n * fact (n-1)); } old TOS caller rt addr • Stack state after execution of second encounter with the jal instruction (third call to fact routine with $a0 now holding 0) • saved return address of instruction in caller routine (instruction after jal) on the stack • saved previous value of $a0 on the stack $a0 = 2 bk_f $a0 = 1  $sp bk_f bk_f $ra 0 $a0 $v0

  31. A Look at the Stack for $a0 = 2 int fact (int n) { if (n < 1) return 1; else return (n * fact (n-1)); } old TOS caller rt addr fact: addi $sp, $sp, -8 sw $ra, 4($sp) sw $a0, 0($sp) slt $t0, $a0, 1 beq $t0, $zero, L1 addi $v0, $zero, 1 addi $sp, $sp, 8 jr $ra L1: addi $a0, $a0, -1 jal fact bk_f: lw $a0, 0($sp) lw $ra, 4($sp) addi $sp, $sp, 8 mul $v0, $a0, $v0 jr $ra $a0 = 2 bk_f  $sp $a0 = 1 bk_f $a0 = 0 bk_f $ra 0 $a0 1 $v0

  32. A Look at the Stack for $a0 = 2 int fact (int n) { if (n < 1) return 1; else return (n * fact (n-1)); } old TOS caller rt addr $a0 = 2 • Stack state after execution of first encounter with the first jr instruction ($v0 initialized to 1) • stack pointer updated to point to third call to fact bk_f  $sp $a0 = 1 bk_f $ra 0 $a0 1 $v0

  33. A Look at the Stack for $a0 = 2 int fact (int n) { if (n < 1) return 1; else return (n * fact (n-1)); } old TOS caller rt addr fact: addi $sp, $sp, -8 sw $ra, 4($sp) sw $a0, 0($sp) slt $t0, $a0, 1 beq $t0, $zero, L1 addi $v0, $zero, 1 addi $sp, $sp, 8 jr $ra L1: addi $a0, $a0, -1 jal fact bk_f: lw $a0, 0($sp) lw $ra, 4($sp) addi $sp, $sp, 8 mul $v0, $a0, $v0 jr $ra $a0 = 2 bk_f  $sp $a0 = 1 bk_f $ra 1 0 $a0 1*1 = 1 1 $v0

  34. A Look at the Stack for $a0 = 2 int fact (int n) { if (n < 1) return 1; else return (n * fact (n-1)); } old TOS • Stack state after execution of first encounter with the second jr instruction (return from fact routine after updating $v0 to 1 * 1) • return address to caller routine (bk_f in fact routine) restored to $ra from the stack • previous value of $a0 restored from the stack • stack pointer updated to point to second call to fact caller rt addr $a0 = 2  $sp bk_f $ra 1 $a0 1 $v0

  35. A Look at the Stack for $a0 = 2 int fact (int n) { if (n < 1) return 1; else return (n * fact (n-1)); } old TOS caller rt addr fact: addi $sp, $sp, -8 sw $ra, 4($sp) sw $a0, 0($sp) slt $t0, $a0, 1 beq $t0, $zero, L1 addi $v0, $zero, 1 addi $sp, $sp, 8 jr $ra L1: addi $a0, $a0, -1 jal fact bk_f: lw $a0, 0($sp) lw $ra, 4($sp) addi $sp, $sp, 8 mul $v0, $a0, $v0 jr $ra  $sp $a0 = 2 caller rt addr bk_f $ra 1 2 $a0 2*1 = 2 1 $v0

  36. A Look at the Stack for $a0 = 2 int fact (int n) { if (n < 1) return 1; else return (n * fact (n-1)); }  $sp old TOS • Stack state after execution of second encounter with the second jr instruction (return from fact routine after updating $v0 to 1 * 1 * 2) • return address to caller routine (main routine) restored to $ra from the stack • original value of $a0 restored from the stack • stack pointer updated to point to first call to fact caller rt addr $ra 2 $a0 2 $v0

  37. MIPS Register Convention

  38. MIPS Instructions

  39. Yoda says… • Do or do not... there is no try

More Related