The MIPS Instruction Set Architecture Computer Science 104 Lectures 7+8 2 © Andrew Hilton / Alvin R. Lebeck CPS 104 • Homework − Homework 1 due tonight − Homework 2 available tonight • Reading: − Finish up Chapter 2 − Appendix B: reference on MIPS Skim: B.7, Fig B.10.2, Insn listing • Midterm 1 − Wed Feb 15 (just over a week) − Material: Lecture through Wed Feb 8 (rec Fri Feb 10) Homework 1 / Homework 2 Reading Chapters 1, 2. Appendix B − Can bring one page of notes Admin 3 © Andrew Hilton / Alvin R. Lebeck Last time… • What did we talk about last time? CPS 104 4 © Andrew Hilton / Alvin R. Lebeck Last time… • What did we talk about last time? − Instruction Set Architecture (ISA) Contract between HW and SW RISC/CISC Accumulator, Stack, 2-address, 3-address Registers Instructions encoded as numbers MIPS CPS 104 5 © Andrew Hilton / Alvin R. Lebeck • 32-bit fixed format instruction (3 formats) • 32 general purpose (R0 contains zero) • 3-address, reg-reg arithmetic instruction • Single address mode for load/store: base + displacement − no indirection CPS 104 See Also: SPARC, MC88100, AMD2900, i960, i860 PARisc, POWERPC, DEC Alpha, Clipper, CDC 6600, CDC 7600, Cray-1, Cray-2, Cray-3 MIPS: A "Typical" RISC 6 © Andrew Hilton / Alvin R. Lebeck MIPS Assembly • Diving into MIPS − Specific example of an ISA (now) − Do some assembly programming (now) − Concrete reference point for hw discussion (later) CPS 104 7 © Andrew Hilton / Alvin R. Lebeck But I don’t have a MIPS computer? • We’ll be using SPIM (on linux.cs) − Command line version: spim − Graphical version: xspim • Edit in emacs, run in SPIM CPS 104 8 © Andrew Hilton / Alvin R. Lebeck Assembly • Assembly programming: − 1 (sometimes two) machine instructions at a time − Still in “human readable form” add r1, r2, r3 − Much “lower level” than any other programming Limited number of registers vs unlimited variables Flat scope (who can remind us what scope is? Hint: not mouthwash) CPS 104 9 © Andrew Hilton / Alvin R. Lebeck CPS 104 Assembly too high level for machine • Human readable is not (easily) machine executable − add r1, r2, r3 • Instructions are numbers too! − Bit fields (like FP numbers) • Instruction Format − establishes a mapping from “instruction” to binary values − which bit positions correspond to which parts of the instruction (operation, operands, etc.) • Assembler does this translation − Humans don’t typically need to write raw bits 10 © Andrew Hilton / Alvin R. Lebeck CPS 104 What Must be Specified? • Instruction “opcode” − What should this operation do? (add, subtract,…) • Location of operands and result − Registers (which ones?) − Memory (what address?) − Immediates (what value?) • Data type and Size − Usually included in opcode • What instruction comes next? − Sequentially next instruction, or jump elsewhere 11 © Andrew Hilton / Alvin R. Lebeck CPS 104 Example: MIPS Op 31 26 0 15 16 20 21 25 Rs1 Rd immediate Op 31 26 0 25 Op 31 26 0 15 16 20 21 25 Rs1 Rs2 target Rd Opx Register-Register 5 6 10 11 Register-Immediate Op 31 26 0 15 16 20 21 25 Rs1 Rs2/Opx immediate Branch Jump / Call 12 © Andrew Hilton / Alvin R. Lebeck CPS 104 Stored Program Computer • Instructions: a fixed set of built-in operations • Instructions and data are stored in memory − Allows general purpose computation! • Fetch-Execute Cycle while (!done) fetch instruction execute instruction • This is done by the hardware for speed • This is what the SPIM Simulator does Stack Data Text Reserved 0 2n-1 Heap 13 © Andrew Hilton / Alvin R. Lebeck CPS 104 Instruction Fetch Instruction Decode Operand Fetch Execute Result Store Next Instruction How are Instructions Executed? • Instruction Fetch: Read instruction bits from memory 14 © Andrew Hilton / Alvin R. Lebeck CPS 104 Instruction Fetch Instruction Decode Operand Fetch Execute Result Store Next Instruction How are Instructions Executed? • Instruction Fetch: Read instruction bits from memory • Decode: Figure out what those bits mean 15 © Andrew Hilton / Alvin R. Lebeck CPS 104 Instruction Fetch Instruction Decode Operand Fetch Execute Result Store Next Instruction How are Instructions Executed? • Instruction Fetch: Read instruction bits from memory • Decode: Figure out what those bits mean • Operand Fetch: Read registers + mem to get sources 16 © Andrew Hilton / Alvin R. Lebeck CPS 104 Instruction Fetch Instruction Decode Operand Fetch Execute Result Store Next Instruction How are Instructions Executed? • Instruction Fetch: Read instruction bits from memory • Decode: Figure out what those bits mean • Operand Fetch: Read registers + mem to get sources • Execute: Do the actual operation (e.g., add the #s) 17 © Andrew Hilton / Alvin R. Lebeck CPS 104 Instruction Fetch Instruction Decode Operand Fetch Execute Result Store Next Instruction How are Instructions Executed? • Instruction Fetch: Read instruction bits from memory • Decode: Figure out what those bits mean • Operand Fetch: Read registers + mem to get sources • Execute: Do the actual operation (e.g., add the #s) • Result Store: Write result to register or memory 18 © Andrew Hilton / Alvin R. Lebeck CPS 104 Instruction Fetch Instruction Decode Operand Fetch Execute Result Store Next Instruction How are Instructions Executed? • Instruction Fetch: Read instruction bits from memory • Decode: Figure out what those bits mean • Operand Fetch: Read registers + mem to get sources • Execute: Do the actual operation (e.g., add the #s) • Result Store: Write result to register or memory • Next Instruction: Figure out mem addr of next insn, repeat 19 © Andrew Hilton / Alvin R. Lebeck CPS 104 More Details on Execution? • Previous slides high level overview • More details: How hardware works − Everything after Midterm 1 • Now, diving into assembly programming/MIPS 20 © Andrew Hilton / Alvin R. Lebeck Programming • How do you write an assembly program? • How do you write a program (in general)? CPS 104 21 © Andrew Hilton / Alvin R. Lebeck How to Write a Program • How I teach programming: 1. Work an example yourself 2. Write down what you did 3. Generalize steps from 2 4. Test generalized steps on different example 5. Translate generalized steps to code CPS 104 22 © Andrew Hilton / Alvin R. Lebeck How to Write a Program • How I teach programming: 1. Work an example yourself 2. Write down what you did 3. Generalize steps from 2 4. Test generalized steps on different example 5. Translate generalized steps to code CPS 104 Develop Algorithm In (Familiar) Higher Level Language Then translate to lower level language 23 © Andrew Hilton / Alvin R. Lebeck Why do I bring this up? • Very Hard: • Easier: CPS 104 Problem Correctly Working Assembly Problem Correctly Working Assembly Algorithm C Implementation 24 © Andrew Hilton / Alvin R. Lebeck Our focus • We will focus on the C assembly step − Assume you know how to devise an algorithm for a problem (Intro programming classes) − And have been learning how to implement algorithm in C (Last few weeks, hwk1) CPS 104 Problem Correctly Working Assembly Algorithm C Implementation 25 © Andrew Hilton / Alvin R. Lebeck Simplest Operations We Might Want? • What is the simplest computation we might do? CPS 104 26 © Andrew Hilton / Alvin R. Lebeck Simplest Operations We Might Want? • What is the simplest computation we might do? − Add two numbers: x = a + b; CPS 104 27 © Andrew Hilton / Alvin R. Lebeck Simplest Operations We Might Want? • What is the simplest computation we might do? − Add two numbers: x = a + b; add $r1, $r2, $r3 “Add r2 + r3, and store it in r1” Note: when writing assembly, basically pick reg for a, reg for b, reg for x Not enough regs for all variables? We’ll talk about that later… CPS 104 28 © Andrew Hilton / Alvin R. Lebeck CPS 104 • Recall: registers − Fast − In CPU − Directly compute on them • 31 x 32-bit GPRs (R0 = 0) • Also FP registers • A few special purpose regs too − PC = Address of next insn MIPS Integer Registers 29 © Andrew Hilton / Alvin R. Lebeck Executing Add CPS 104 Register Value R0 0000 0000 R1 1234 5678 R2 C001 D00D R3 1BAD F00D R4 9999 9999 R5 ABAB ABAB R6 0000 0001 R7 0000 0002 R8 0000 0000 R9 0000 0000 R10 0000 0000 R11 0000 0000 R12 0000 0000 … … PC 0000 1000 Address Instruction 1000 add $r8, $r4, $r6 1004 add $r5, $r8, $r7 1008 add $r6, $r6, $r6 100C … 1010 … PC tells us where to execute next 30 © Andrew Hilton / Alvin R. Lebeck Executing Add CPS 104 Register Value R0 0000 0000 R1 1234 5678 R2 C001 D00D R3 1BAD F00D R4 9999 9999 R5 ABAB ABAB R6 0000 0001 R7 0000 0002 R8 0000 0000 R9 0000 0000 R10 0000 0000 R11 0000 0000 R12 0000 0000 … … PC 0000 1000 Address Instruction 1000 add $r8, $r4, $r6 1004 add $r5, $r8, $r7 1008 add $r6, $r6, $r6 100C … 1010 … Add reads its source registers, and uses their values directly (“register direct”) 9999 9999 0000 0001 9999 999A 31 © Andrew Hilton / Alvin R. Lebeck Executing Add CPS 104 Register Value R0 0000 0000 R1 1234 5678 R2 C001 D00D R3 1BAD F00D R4 9999 9999 R5 ABAB ABAB R6 0000 0001 R7 0000 0002 R8 9999 999A R9 0000 0000 R10 0000 0000 R11 0000 0000 R12 0000 0000 … … PC 0000 1000 Address Instruction 1000 add $r8, $r4, $r6 1004 add $r5, $r8, $r7 1008 add $r6, $r6, $r6 100C … 1010 … Add writes its result to its destination register 32 © Andrew Hilton / Alvin R. Lebeck Executing Add CPS 104 Register Value R0 0000 0000 R1 1234 5678 R2 C001 D00D R3 1BAD F00D R4 9999 9999 R5 ABAB ABAB R6 0000 0001 R7 0000 0002 R8 9999 999A R9 0000 0000 R10 0000 0000 R11 0000 0000 R12 0000 0000 … … PC 0000 1004 Address Instruction 1000 add $r8, $r4, $r6 1004 add $r5, $r8, $r7 1008 add $r6, $r6, $r6 100C … 1010 … And goes to the sequentially next instruction (PC = PC + 4) 33 © Andrew Hilton / Alvin R. Lebeck Executing Add CPS 104 Register Value R0 0000 0000 R1 1234 5678 R2 C001 D00D R3 1BAD F00D R4 9999 9999 R5 ABAB ABAB R6 0000 0001 R7 0000 0002 R8 9999 999A R9 0000 0000 R10 0000 0000 R11 0000 0000 R12 0000 0000 … … PC 0000 1004 Address Instruction 1000 add $r8, $r4, $r6 1004 add $r5, $r8, $r7 1008 add $r6, $r6, $r6 100C … 1010 … You all do the next instruction! 34 © Andrew Hilton / Alvin R. Lebeck Executing Add CPS 104 Register Value R0 0000 0000 R1 1234 5678 R2 C001 D00D R3 1BAD F00D R4 9999 9999 R5 9999 999C R6 0000 0001 R7 0000 0002 R8 9999 999A R9 0000 0000 R10 0000 0000 R11 0000 0000 R12 0000 0000 … … PC 0000 1008 Address Instruction 1000 add $r8, $r4, $r6 1004 add $r5, $r8, $r7 1008 add $r6, $r6, $r6 100C … 1010 … We set r5 equal to $r8 (9999 999A) + $r7 (2) = 9999 999C and PC = PC +4 35 © Andrew Hilton / Alvin R. Lebeck Executing Add CPS 104 Register Value R0 0000 0000 R1 1234 5678 R2 C001 D00D R3 1BAD F00D R4 9999 9999 R5 9999 999C R6 0000 0001 R7 0000 0002 R8 9999 999A R9 0000 0000 R10 0000 0000 R11 0000 0000 R12 0000 0000 … … PC 0000 1008 Address Instruction 1000 add $r8, $r4, $r6 1004 add $r5, $r8, $r7 1008 add $r6, $r6, $r6 100C … 1010 … Its perfectly fine to have $r6 as a src and a dst This is just like x = x + x; in C, Java, etc: 1 + 1 = 2 36 © Andrew Hilton / Alvin R. Lebeck Executing Add CPS 104 Register Value R0 0000 0000 R1 1234 5678 R2 C001 D00D R3 1BAD F00D R4 9999 9999 R5 9999 999C R6 0000 0002 R7 0000 0002 R8 9999 999A R9 0000 0000 R10 0000 0000 R11 0000 0000 R12 0000 0000 … … PC 0000 100C Address Instruction 1000 add $r8, $r4, $r6 1004 add $r5, $r8, $r7 1008 add $r6, $r6, $r6 100C … 1010 … Its perfectly fine to have $r6 as a src and a dst This is just like x = x + x; in C, Java, etc: 1 + 1 = 2 37 © Andrew Hilton / Alvin R. Lebeck CPS 104 MIPS Instruction Formats Op 31 26 0 15 16 20 21 25 Rs Rt immediate Op 31 26 0 25 target R-type: Register-Register Op 31 26 0 15 16 20 21 25 Rs Rt shamt Rd func 5 6 10 11 I-type: Register-Immediate J-type: Jump / Call Terminology Op = opcode Rs, Rt, Rd = register specifier 38 © Andrew Hilton / Alvin R. Lebeck CPS 104 op a 6-bit operation code. rs a 5-bit source register. rt a 5-bit target (source) register. rd a 5-bit destination register. shmt a 5-bit shift amount. func a 6-bit function field. Example: add $1, $2, $3 R Type:rd, rs, rt 31 26 0 15 16 20 21 25 5 6 10 11 Op Rs Rt Rd shmt func op rs rt rd shmt func 000000 00010 00011 00001 00000 100000 39 © Andrew Hilton / Alvin R. Lebeck Executing Add CPS 104 Register Value R0 0000 0000 R1 1234 5678 R2 C001 D00D R3 1BAD F00D R4 9999 9999 R5 9999 999C R6 0000 0002 R7 0000 0002 R8 9999 999A R9 0000 0000 R10 0000 0000 R11 0000 0000 R12 0000 0000 … … PC 0000 100C Address Instruction Insn Val 1000 add $r8, $r4, $r6 0086 4020 1004 add $r5, $r8, $r7 0107 2820 1008 add $r6, $r6, $r6 00C6 3020 100C … … 1010 … … 40 © Andrew Hilton / Alvin R. Lebeck Xspim: Shows you similar state CPS 104 Register Values Insn Memory 41 © Andrew Hilton / Alvin R. Lebeck Other Similar Instructions sub $rDest, $rSrc1, $rSrc2 mul $rDest, $rSrc1, $rSrc2 (pseudo-insn) div $rDest, $rSrc1, $rSrc2 (pseudo-insn) and $rDest, $rSrc1, $rSrc2 or $rDest, $rSrc1, $rSrc2 xor $rDest, $rSrc1, $rSrc2 … • End of Appendix B: listing of all instructions CPS 104 42 © Andrew Hilton / Alvin R. Lebeck Pseudo Instructions • Some “instructions” are pseudo-instructions − Actually assemble into 2 instructions: • mul $r1, $r2, $r3 is really mul $r2, $r3 mflo $r1 mul takes two srcs, writes special regs lo and hi mflo moves from lo into dst reg CPS 104 43 © Andrew Hilton / Alvin R. Lebeck What if I want to add a constant? • Suppose I need to do x = x + 1 − Idea one: Put 1 in a register, use add Problem: How to put 1 in a register? − Idea two: Have instruction that adds immediate Note: also solves problem in idea one CPS 104 44 © Andrew Hilton / Alvin R. Lebeck CPS 104 Immediate: 16 bit value Operand Addressing: Register Direct and Immediate Add Immediate Example addi $1, $2, 100 I-Type rt, rs, immediate 31 26 0 15 16 20 21 25 Op Rs Rt Immediate op rs rt immediate 001000 00010 00001 0000 0000 0110 0100 45 © Andrew Hilton / Alvin R. Lebeck Using addi to put a const in register Can use addi to put a constant into a register: x = 42; Can be done with addi $r7, $r0, 42 Because $r0 is always 0. Common enough it has its own pseudo-insn: li $r7, 42 Stands for load immediate, works for 16-bit immediate CPS 104 46 © Andrew Hilton / Alvin R. Lebeck Many insns have Immediate Forms • Add is not the only one with an immediate form − andi, ori, xori,sll,sr,sra,… • No subi − Why not? • No muli or divi − Though some ISAs have them − CPS 104 47 © Andrew Hilton / Alvin R. Lebeck Assembly programming something “useful” Consider the following C fragment: int tempF = 87; int a = tempF – 32; a = a * 5; int tempC = a / 9; Lets write assembly for it CPS 104 48 © Andrew Hilton / Alvin R. Lebeck Assembly programming something “useful” Consider the following C fragment: int tempF = 87; int a = tempF – 32; a = a * 5; int tempC = a / 9; Lets write assembly for it − First, need registers for our variables: tempF = $r3 a = $r4 tempC = $r5 − Now, give it a try (use $r6, $r7,… as temps if you need)… CPS 104 49 © Andrew Hilton / Alvin R. Lebeck Assembly programming something “useful” Consider the following C fragment: int tempF = 87; li $r3, 87 int a = tempF – 32; addi $r4, $r3, -32 a = a * 5; li $r6, 5 int tempC = a / 9; mul $r4, $r4, $r6 li $r6, 9 Lets write assembly for it div $r5, $r4, $r6 − First, need registers for our variables: tempF = $r3 a = $r4 tempC = $r5 − Now, give it a try (use $r6, $r7,… as temps if you need)… CPS 104 50 © Andrew Hilton / Alvin R. Lebeck Accessing Memory • MIPS is a “load-store” ISA − Who can remind us what that means? CPS 104 51 © Andrew Hilton / Alvin R. Lebeck Accessing Memory • MIPS is a “load-store” ISA − Who can remind us what that means? Only load and store insns access memory (and that is all those isns do) Contrast to x86, which allows add reg = (memory location) + reg Or even add (memory location) = (memory location) + reg CPS 104 52 © Andrew Hilton / Alvin R. Lebeck CPS 104 Load Word Example lw $1, 100($2) # $1 = Mem[$2+100] Base+index I-Type rt, rs, immediate Register + Memory 31 26 0 15 16 20 21 25 Op Rs Rt Immediate Register op rs rt immediate 100011 00010 00001 0000 0000 0110 0100 53 © Andrew Hilton / Alvin R. Lebeck CPS 104 Store Word Example sw $1, 100($2) # Mem[$2+100] = $1 Base+index I-Type rt, rs, immediate Register + Memory 31 26 0 15 16 20 21 25 Op Rs Rt Immediate Register op rs rt immediate 100011 00010 00001 0000 0000 0110 0100 54 © Andrew Hilton / Alvin R. Lebeck Data sizes / types • Loads and Stores come in multiple sizes − Reflect different data types • The w in lw/sw stands for “word” (= 32 bits) − Can also load bytes (8 bits), half words (16 bits) − Smaller sizes have signed/unsigned forms − See Appendix B for all variants CPS 104 55 © Andrew Hilton / Alvin R. Lebeck C and assembly: loads/stores int x int * p int ** q … x = *p; **q = x; p = *q; p[4] = x; # in r1 # in r2 # in r3 … CPS 104 56 © Andrew Hilton / Alvin R. Lebeck C and assembly: loads/stores int x int * p int ** q … x = *p; **q = x; p = *q; p[4] = x; # in r1 # in r2 # in r3 … lw $r1, 0($r2) CPS 104 57 © Andrew Hilton / Alvin R. Lebeck C and assembly: loads/stores int x int * p int ** q … x = *p; **q = x; p = *q; p[4] = x; # in r1 # in r2 # in r3 … lw $r1, 0($r2) lw $r4, 0($r3) sw $r1, 0($r4) CPS 104 58 © Andrew Hilton / Alvin R. Lebeck C and assembly: loads/stores int x int * p int ** q … x = *p; **q = x; p = *q; p[4] = x; # in r1 # in r2 # in r3 … lw $r1, 0($r2) lw $r4, 0($r3) sw $r1, 0($r4) lw $r2, 0($r3) sw $r1, 16($r2) CPS 104 59 © Andrew Hilton / Alvin R. Lebeck Executing Memory Ops CPS 104 Register Value R0 0000 0000 R1 1234 5678 R2 0000 8004 R3 0000 8010 R4 9999 9999 R5 9999 999C R6 0000 0002 R7 0000 0002 R8 9999 999A R9 0000 0000 R10 0000 0000 R11 0000 0000 R12 0000 0000 … … PC 0000 1000 Address Value 1000 lw $r1, 0($r2) 1004 lw $r4, 4($r3) 1008 sw $r1, 8($r4) 100C lw $r2, 0($r3) 1010 … … … 8000 F00D F00D 8004 C001 D00D 8008 1234 4321 8010 4242 4242 8014 0000 8000 60 © Andrew Hilton / Alvin R. Lebeck Executing Memory Ops CPS 104 Register Value R0 0000 0000 R1 1234 5678 R2 0000 8004 R3 0000 8010 R4 9999 9999 R5 9999 999C R6 0000 0002 R7 0000 0002 R8 9999 999A R9 0000 0000 R10 0000 0000 R11 0000 0000 R12 0000 0000 … … PC 0000 1000 Address Value 1000 lw $r1, 0($r2) 1004 lw $r4, 4($r3) 1008 sw $r1, 8($r4) 100C lw $r2, 0($r3) 1010 … … … 8000 F00D F00D 8004 C001 D00D 8008 1234 4321 8010 4242 4242 8014 0000 8000 61 © Andrew Hilton / Alvin R. Lebeck Executing Memory Ops CPS 104 Register Value R0 0000 0000 R1 C001 D00D R2 0000 8004 R3 0000 8010 R4 9999 9999 R5 9999 999C R6 0000 0002 R7 0000 0002 R8 9999 999A R9 0000 0000 R10 0000 0000 R11 0000 0000 R12 0000 0000 … … PC 0000 1004 Address Value 1000 lw $r1, 0($r2) 1004 lw $r4, 4($r3) 1008 sw $r1, 8($r4) 100C lw $r2, 0($r3) 1010 … … … 8000 F00D F00D 8004 C001 D00D 8008 1234 4321 8010 4242 4242 8014 0000 8000 62 © Andrew Hilton / Alvin R. Lebeck Executing Memory Ops CPS 104 Register Value R0 0000 0000 R1 C001 D00D R2 0000 8004 R3 0000 8010 R4 0000 8000 R5 9999 999C R6 0000 0002 R7 0000 0002 R8 9999 999A R9 0000 0000 R10 0000 0000 R11 0000 0000 R12 0000 0000 … … PC 0000 1008 Address Value 1000 lw $r1, 0($r2) 1004 lw $r4, 4($r3) 1008 sw $r1, 8($r4) 100C lw $r2, 0($r3) 1010 … … … 8000 F00D F00D 8004 C001 D00D 8008 1234 4321 8010 4242 4242 8014 0000 8000 63 © Andrew Hilton / Alvin R. Lebeck Executing Memory Ops CPS 104 Register Value R0 0000 0000 R1 C001 D00D R2 0000 8004 R3 0000 8010 R4 0000 8000 R5 9999 999C R6 0000 0002 R7 0000 0002 R8 9999 999A R9 0000 0000 R10 0000 0000 R11 0000 0000 R12 0000 0000 … … PC 0000 100C Address Value 1000 lw $r1, 0($r2) 1004 lw $r4, 4($r3) 1008 sw $r1, 8($r4) 100C lw $r2, 0($r3) 1010 … … … 8000 F00D F00D 8004 C001 D00D 8008 C001 D00D 8010 4242 4242 8014 0000 8000 64 © Andrew Hilton / Alvin R. Lebeck Executing Memory Ops CPS 104 Register Value R0 0000 0000 R1 C001 D00D R2 4242 4242 R3 0000 8010 R4 0000 8000 R5 9999 999C R6 0000 0002 R7 0000 0002 R8 9999 999A R9 0000 0000 R10 0000 0000 R11 0000 0000 R12 0000 0000 … … PC 0000 1010 Address Value 1000 lw $r1, 0($r2) 1004 lw $r4, 4($r3) 1008 sw $r1, 8($r4) 100C lw $r2, 0($r3) 1010 … … … 8000 F00D F00D 8004 C001 D00D 8008 C001 D00D 8010 4242 4242 8014 0000 8000 65 © Andrew Hilton / Alvin R. Lebeck CPS 104 Making control decision Control constructs−decide what to do next: if (x == y) { … } else { … } … while (z < q) { … } Instruction Fetch Instruction Decode Operand Fetch Execute Result Store Next Instruction 66 © Andrew Hilton / Alvin R. Lebeck CPS 104 The Program Counter (PC) • Special register (PC) that points to instructions • Contains memory address (like a pointer) • Instruction fetch is − inst = mem[pc] • So far, have fetched sequentially: PC= PC + 4 − Assumes 4 byte insns − True for MIPS − X86: variable size (nasty) • May want to specify non-sequential fetch − Change PC in other ways 67 © Andrew Hilton / Alvin R. Lebeck CPS 104 • PC relative addressing Branch Not Equal Example bne $1, $2, 100 # If ($1!= $2) goto [PC+4+400] //why 400? • +4 because by default we increment for sequential − more detailed discussion later in semester I-Type rt, rs, immediate PC + 31 26 0 15 16 20 21 25 Op Rs Rt Immediate op rs rt immediate 000101 00001 00010 0000 0000 0110 0100 + 4 00 68 © Andrew Hilton / Alvin R. Lebeck CPS 104 MIPS Compare and Branch Compare and Branch beq rs, rt, offset if R[rs] == R[rt] then PC-relative branch bne rs, rt, offset <> Compare to zero and Branch blez rs, offset if R[rs] <= 0 then PC-relative branch bgtz rs, offset > bltz rs, offset < bgez rs, offset >= bltzal rs, offset if R[rs] < 0 then branch and link (into R 31) bgeal rs, offset >= Also pseudo-insns for unconditional branch (b) 69 © Andrew Hilton / Alvin R. Lebeck CPS 104 MIPS jump, branch, compare instructions Other compare: require 2 insns Conditionally set reg, branch if not zero or if zero Instruction Example Meaning set on less than slt $1,$2,$3 $1=($2<$3) ? 1 : 0 Compare less than; signed 2’s comp. set less than imm. slti $1,$2,100 $1 = ($2 < 100) ? 1 : 0 Compare < constant; signed 2’s comp. set less than uns. sltu $1,$2,$3 $1 = ($2 < $3) ? 1 : 0 Compare less than; unsigned set l. t. imm. uns. sltiu $1,$2,100 $1 = ($2 < $3) ? 1 : 0 $1=0 Compare < constant; unsigned Branch if zero beqz $1,100 if ($1 == $2) go to PC+4+400 Branch if not zero bnez $1,100 if ($1!= $2) go to PC+4+400 70 © Andrew Hilton / Alvin R. Lebeck CPS 104 R1= 0…00 0000 0000 0000 0001 R2= 0…00 0000 0000 0000 0010 R3= 1…11 1111 1111 1111 1111 • After executing these instructions: slt r4,r2,r1 slt r5,r3,r1 sltu r6,r2,r1 sltu r7,r3,r1 • What are values of registers r4 - r7? Why? r4 = ; r5 = ; r6 = ; r7 = ; Signed v.s. Unsigned Comparison 71 © Andrew Hilton / Alvin R. Lebeck CPS 104 R1= 0…00 0000 0000 0000 0001 R2= 0…00 0000 0000 0000 0010 R3= 1…11 1111 1111 1111 1111 • After executing these instructions: slt r4,r2,r1 slt r5,r3,r1 sltu r6,r2,r1 sltu r7,r3,r1 • What are values of registers r4 - r7? Why? r4 = 0 ; r5 = 1 ; r6 = 0 ; r7 = 0 ; Signed v.s. Unsigned Comparison 72 © Andrew Hilton / Alvin R. Lebeck C and Assembly with branches int x; int y; int z; … if (x != y) { z = z + 2; } else { Z = z -4; } //assume x in r1 //assume y in r2 //assume z in r3 … bne $r1,$r2, 2 addi $r3, $r3, 2 b 1 addi $r3, $r3, -4 CPS 104 73 © Andrew Hilton / Alvin R. Lebeck Labels Counting insns? Error prone Tricky: pseudo-insns Un-maintainable Better: let assembler count Use a label Symbolic name for target Assembler computes offset //assume x in r1 //assume y in r2 //assume z in r3 … bne $r1,$r2, L_else addi $r3, $r3, 2 b L_end L_else: addi $r3, $r3, -4 L_end: CPS 104 74 © Andrew Hilton / Alvin R. Lebeck CPS 104 • 16-bit imm limits to +/- 32K insns • Usually fine, but sometimes need more… • J-type insns provide long range, unconditional jump: • Specifies lowest 28 bits of PC − Upper 4 bits unchanged − Range: 64 Million instruction (256 MB) • Can jump anywhere with jr $reg (jump register) J-Type immediate 31 26 0 15 16 20 21 25 Op Rs Rt Immediate 31 26 Op Target Address 0 75 © Andrew Hilton / Alvin R. Lebeck Remember our F2C program fragment? Consider the following C fragment: int tempF = 87; li $r3, 87 int a = tempF – 32; addi $r4, $r3, -32 a = a * 5; li $r6, 5 int tempC = a / 9; mul $r4, $r4, $r6 li $r6, 9 If we were really doing this… div $r5, $r4, $r6 We would write a function to convert f2c and call it CPS 104 76 © Andrew Hilton / Alvin R. Lebeck More likely: a function to convert • Like this: int f2c (int tempF) { int a = tempF – 32; a = a * 5; int tempC = a / 9; return tempC; } … … int tempC = f2c (87); CPS 104 77 © Andrew Hilton / Alvin R. Lebeck Need a way to call f2c and return • Call: Jump… but also remember where to go back − May be many calls to f2c() in the program − Need some way to know where we were • Return: Jump… back to wherever we were CPS 104 78 © Andrew Hilton / Alvin R. Lebeck CPS 104 Jump and Link (“Call”) Example JAL 1000 # $31<-PC+4, PC <- 4000 $31 set as side effect, used for returning, implicit operand J-Type: target PC 31 26 Op Target Address op Target 000011 00 0000 0000 0000 0011 1110 1000 $31 + 4 00 79 © Andrew Hilton / Alvin R. Lebeck CPS 104 Jump Register Example jr $31 # PC <- $31 R Type: rd, rs, rt 31 26 0 15 16 20 21 25 5 6 10 11 Op Rs Rt Rd shamt func op rs rt rd shmt func 000000 11111 00000 00000 00000 001000 80 © Andrew Hilton / Alvin R. Lebeck More likely: a function to convert • Like this: int f2c (int tempF) { int a = tempF – 32; a = a * 5; int tempC = a / 9; return tempC; } //jr $31 … … int tempC = f2c (87); //jal f2c But that’s not all… CPS 104 81 © Andrew Hilton / Alvin R. Lebeck More likely: a function to convert • Like this: int f2c (int tempF) { int a = tempF – 32; a = a * 5; int tempC = a / 9; return tempC; } //jr $31 … … int tempC = f2c (87); //jal f2c Need to pass 87 as tempF argument CPS 104 82 © Andrew Hilton / Alvin R. Lebeck More likely: a function to convert • Like this: int f2c (int tempF) { int a = tempF – 32; a = a * 5; int tempC = a / 9; return tempC; } //jr $31 … … int tempC = f2c (87); //jal f2c Need return tempC properly Remember no scope in assembly CPS 104 83 © Andrew Hilton / Alvin R. Lebeck More likely: a function to convert • Like this: int f2c (int tempF) { int a = tempF – 32; a = a * 5; int tempC = a / 9; return tempC; } //jr $31 … … int tempC = f2c (87); //jal f2c Also: may want to use same registers in different functions CPS 104 84 © Andrew Hilton / Alvin R. Lebeck Calling Convention • All of these are reasons for a calling convention − Agreement of how registers are used − Where arguments are passed, results returned − Who must save what if they want to use it − Etc.. • Alternative: inter-procedural register allocation − More work for compiler − Only know one real compiler that does this CPS 104 85 © Andrew Hilton / Alvin R. Lebeck CPS 104 0 zero constant 0 1 at reserved for assembler 2 v0 expression evaluation & 3 v1 function results 4 a0 arguments 5 a1 6 a2 7 a3 8 t0 temporary: caller saves . . . 15 t7 16 s0 callee saves . . . 23 s7 24 t8 temporary (cont’d) 25 t9 26 k0 reserved for OS kernel 27 k1 28 gp Pointer to global area 29 sp Stack pointer 30 fp frame pointer 31 ra Return Address (HW) MIPS Register Naming Conventions 86 © Andrew Hilton / Alvin R. Lebeck More likely: a function to convert int f2c (int tempF) { int a = tempF – 32; a = a * 5; int tempC = a / 9; return tempC; } f2c: addi $t0, $a0, -32 CPS 104 tempF is in $a0 by calling convention 87 © Andrew Hilton / Alvin R. Lebeck More likely: a function to convert int f2c (int tempF) { int a = tempF – 32; a = a * 5; int tempC = a / 9; return tempC; } f2c: addi $t0, $a0, -32 CPS 104 We can use $t0 for a temp (like a) without saving it 88 © Andrew Hilton / Alvin R. Lebeck More likely: a function to convert int f2c (int tempF) { int a = tempF – 32; a = a * 5; int tempC = a / 9; return tempC; } f2c: addi $t0, $a0, -32 li $t1, 5 mul $t0, $t0, $t1 CPS 104 89 © Andrew Hilton / Alvin R. Lebeck More likely: a function to convert int f2c (int tempF) { int a = tempF – 32; a = a * 5; int tempC = a / 9; return tempC; } f2c: addi $t0, $a0, -32 li $t1, 5 mul $t0, $t0, $t1 li $t1, 9 div $t2, $t0, $t1 CPS 104 90 © Andrew Hilton / Alvin R. Lebeck More likely: a function to convert int f2c (int tempF) { int a = tempF – 32; a = a * 5; int tempC = a / 9; return tempC; } f2c: addi $t0, $a0, -32 li $t1, 5 mul $t0, $t0, $t1 li $t1, 9 div $t2, $t0, $t1 addi $v0, $t2, 0 jr $ra CPS 104 A smart compiler would just do div $v0, $t0, $t1 91 © Andrew Hilton / Alvin R. Lebeck More likely: a function to convert int f2c (int tempF) { int a = tempF – 32; a = a * 5; int tempC = a / 9; return tempC; } … … int tempC = f2c(87) f2c: addi $t0, $a0, -32 li $t1, 5 mul $t0, $t0, $t1 li $t1, 9 div $t2, $t0, $t1 addi $v0, $t2, 0 jr $ra … … addi $a0, $r0, 87 CPS 104 92 © Andrew Hilton / Alvin R. Lebeck More likely: a function to convert int f2c (int tempF) { int a = tempF – 32; a = a * 5; int tempC = a / 9; return tempC; } … … int tempC = f2c(87) f2c: addi $t0, $a0, -32 li $t1, 5 mul $t0, $t0, $t1 li $t1, 9 div $t2, $t0, $t1 addi $v0, $t2, 0 jr $ra … … addi $a0, $r0, 87 jal f2c CPS 104 93 © Andrew Hilton / Alvin R. Lebeck More likely: a function to convert int f2c (int tempF) { int a = tempF – 32; a = a * 5; int tempC = a / 9; return tempC; } … … int tempC = f2c(87) f2c: addi $t0, $a0, -32 li $t1, 5 mul $t0, $t0, $t1 li $t1, 9 div $t2, $t0, $t1 addi $v0, $t2, 0 jr $ra … … addi $a0, $r0, 87 jal f2c addi $t0, $v0, 0 # assume tempC in $t0 CPS 104 94 © Andrew Hilton / Alvin R. Lebeck What it would take to make SPIM happy .globl f2c # f2c can be called from any file .ent f2c # entry point of function .text # goes in “text” region f2c: # (remember memory picture?) addi $t0, $a0, -32 li $t1, 5 mul $t0, $t0, $t1 li $t1, 9 div $t2, $t0, $t1 addi $v0, $t2, 0 jr $ra .end f2c # end of this function CPS 104 95 © Andrew Hilton / Alvin R. Lebeck CPS 104 Assembly Language (cont.) • Directives: tell the assembler what to do... • Format “.” [arg1], [arg2] … • Examples .data [address] # start a data segment. # [optional begining address] .text [address] # start a code segment. .align n # align segment on 2n byte boundary. .ascii # store a string in memory. .asciiz # store a null terminated string in memory .word w1, w2, . . . , wn # store n words in memory. 96 © Andrew Hilton / Alvin R. Lebeck The Stack • May need to use the stack for… − Local variables whose address is taken (Can’t have “address of register”) − Saving registers Across calls Spilling variables (not enough regs) − Passing more than 4 arguments CPS 104 Stack Data Text Reserved 0 2n-1 Heap 97 © Andrew Hilton / Alvin R. Lebeck Stack Layout • Stack is in memory: − Use loads and stores to access − But what address to load/store? • Two registers for stack: − Stack pointer ($sp): Points at end (bottom) of stack − Frame pointer ($fp): Points at top of current stack frame CPS 104 98 © Andrew Hilton / Alvin R. Lebeck CPS 104 $fp ARGS Callee Save Registers Local Variables $sp Arguments and local variables at fixed offset from FP Grows and shrinks as needed (old FP, RA) High Mem Low Mem Dynamic area Argument 5 Argument 6 Call-Return Linkage: Stack Frames Caller’s Frame Current Frame 99 © Andrew Hilton / Alvin R. Lebeck CPS 104 MIPS/GCC Procedure Calling Conventions Calling Procedure • Step-1: Setup the arguments: − The first four arguments (arg0-arg3) are passed in registers $a0-$a3 − Remaining arguments are pushed onto the stack (in reverse order arg5 is at the top of the stack). • Step-2: Save caller-saved registers − Save registers $t0-$t9 if they contain live values at the call site. • Step-3: Execute a jal instruction. • Step-4: Cleanup stack (if more than 4 args) 100 © Andrew Hilton / Alvin R. Lebeck CPS 104 MIPS/GCC Procedure Calling Conventions (cont.) Called Routine (if any frame is needed) • Step-1: Establish stack frame. − Subtract the frame size from the stack pointer. subiu $sp, $sp, − Typically, minimum frame size is 32 bytes (8 words). • Step-2: Save callee saved registers in the frame. − Register $fp is always saved. − Register $ra is saved if routine makes a call. − Registers $s0-$s7 are saved if they are used. • Step-3: Establish Frame pointer − Add the stack - 4 to the address in $sp addiu $fp, $sp, - 4 101 © Andrew Hilton / Alvin R. Lebeck CPS 104 MIPS/GCC Procedure Calling Conventions (cont.) On return from a call • Step-1: Put returned values in registers $v0, [$v1]. (if values are returned) • Step-2: Restore callee-saved registers. − Restore $fp and other saved registers. [$ra, $s0 - $s7] • Step-3: Pop the stack − Add the frame size to $sp. addiu $sp, $sp, • Step-4: Return − Jump to the address in $ra. jr $ra 102 © Andrew Hilton / Alvin R. Lebeck Execution example: Calling with frames CPS 104 Reg Value $r0 0000 0000 $at 0000 0000 $v0 4242 4242 $v1 0000 8010 $a0 0000 1234 $a1 5678 0001 $a2 0000 0002 $a3 0000 0007 $t0 9999 999A $t1 0000 0000 $s0 0042 0420 $sp 0000 FFE0 $fp 0000 FFF0 $ra 0000 2348 PC 0000 1000 Addr Instruction 1000 subiu $sp, $sp, 16 1004 sw $fp, 0($sp) 1008 sw $ra, 4($sp) 100C sw $s0, 8($sp) 1010 addiu $fp, $sp, 12 1014 add $s0, $a0, $a1 1018 jal 4200 101C add $t0, $v0, $s0 1020 lw $v0, 4($t0) 1024 lw $s0, -4($fp) 1028 lw $ra, -8($fp) 102C lw $fp, -12($fp) 1030 addiu $sp, $sp, 16 1034 jr $ra Addr Value FFF0 0001 0070 FFEC 1234 5678 FFE8 9999 9999 FFE4 0000 2568 FFE0 0001 0040 FFDC FFD8 FFD4 FFD0 FFCC FFC8 FFC4 FFC0 FFBC Just did jal 1000 103 © Andrew Hilton / Alvin R. Lebeck Execution example: Calling with frames CPS 104 Reg Value $r0 0000 0000 $at 0000 0000 $v0 4242 4242 $v1 0000 8010 $a0 0000 1234 $a1 5678 0001 $a2 0000 0002 $a3 0000 0007 $t0 9999 999A $t1 0000 0000 $s0 0042 0420 $sp 0000 FFE0 $fp 0000 FFF0 $ra 0000 2348 PC 0000 1000 Addr Instruction 1000 subiu $sp, $sp, 16 1004 sw $fp, 0($sp) 1008 sw $ra, 4($sp) 100C sw $s0, 8($sp) 1010 addiu $fp, $sp, 12 1014 add $s0, $a0, $a1 1018 jal 4200 101C add $t0, $v0, $s0 1020 lw $v0, 4($t0) 1024 lw $s0, -4($fp) 1028 lw $ra, -8($fp) 102C lw $fp, -12($fp) 1030 addiu $sp, $sp, 16 1034 jr $ra Addr Value FFF0 0001 0070 FFEC 1234 5678 FFE8 9999 9999 FFE4 0000 2568 FFE0 0001 0040 FFDC FFD8 FFD4 FFD0 FFCC FFC8 FFC4 FFC0 FFBC $sp, $fp still describe callers frame 104 © Andrew Hilton / Alvin R. Lebeck Execution example: Calling with frames CPS 104 Reg Value $r0 0000 0000 $at 0000 0000 $v0 4242 4242 $v1 0000 8010 $a0 0000 1234 $a1 5678 0001 $a2 0000 0002 $a3 0000 0007 $t0 9999 999A $t1 0000 0000 $s0 0042 0420 $sp 0000 FFD0 $fp 0000 FFF0 $ra 0000 2348 PC 0000 1004 Addr Instruction 1000 subiu $sp, $sp, 16 1004 sw $fp, 0($sp) 1008 sw $ra, 4($sp) 100C sw $s0, 8($sp) 1010 addiu $fp, $sp, 12 1014 add $s0, $a0, $a1 1018 jal 4200 101C add $t0, $v0, $s0 1020 lw $v0, 4($t0) 1024 lw $s0, -4($fp) 1028 lw $ra, -8($fp) 102C lw $fp, -12($fp) 1030 addiu $sp, $sp, 16 1034 jr $ra Addr Value FFF0 0001 0070 FFEC 1234 5678 FFE8 9999 9999 FFE4 0000 2568 FFE0 0001 0040 FFDC FFD8 FFD4 FFD0 FFCC FFC8 FFC4 FFC0 FFBC Allocate space on stack 105 © Andrew Hilton / Alvin R. Lebeck Execution example: Calling with frames CPS 104 Reg Value $r0 0000 0000 $at 0000 0000 $v0 4242 4242 $v1 0000 8010 $a0 0000 1234 $a1 5678 0001 $a2 0000 0002 $a3 0000 0007 $t0 9999 999A $t1 0000 0000 $s0 0042 0420 $sp 0000 FFD0 $fp 0000 FFF0 $ra 0000 2348 PC 0000 1008 Addr Instruction 1000 subiu $sp, $sp, 16 1004 sw $fp, 0($sp) 1008 sw $ra, 4($sp) 100C sw $s0, 8($sp) 1010 addiu $fp, $sp, 12 1014 add $s0, $a0, $a1 1018 jal 4200 101C add $t0, $v0, $s0 1020 lw $v0, 4($t0) 1024 lw $s0, -4($fp) 1028 lw $ra, -8($fp) 102C lw $fp, -12($fp) 1030 addiu $sp, $sp, 16 1034 jr $ra Addr Value FFF0 0001 0070 FFEC 1234 5678 FFE8 9999 9999 FFE4 0000 2568 FFE0 0001 0040 FFDC FFD8 FFD4 FFD0 0000 FFF0 FFCC FFC8 FFC4 FFC0 FFBC Save $fp 106 © Andrew Hilton / Alvin R. Lebeck Execution example: Calling with frames CPS 104 Reg Value $r0 0000 0000 $at 0000 0000 $v0 4242 4242 $v1 0000 8010 $a0 0000 1234 $a1 5678 0001 $a2 0000 0002 $a3 0000 0007 $t0 9999 999A $t1 0000 0000 $s0 0042 0420 $sp 0000 FFD0 $fp 0000 FFF0 $ra 0000 2348 PC 0000 100C Addr Instruction 1000 subiu $sp, $sp, 16 1004 sw $fp, 0($sp) 1008 sw $ra, 4($sp) 100C sw $s0, 8($sp) 1010 addiu $fp, $sp, 12 1014 add $s0, $a0, $a1 1018 jal 4200 101C add $t0, $v0, $s0 1020 lw $v0, 4($t0) 1024 lw $s0, -4($fp) 1028 lw $ra, -8($fp) 102C lw $fp, -12($fp) 1030 addiu $sp, $sp, 16 1034 jr $ra Addr Value FFF0 0001 0070 FFEC 1234 5678 FFE8 9999 9999 FFE4 0000 2568 FFE0 0001 0040 FFDC FFD8 FFD4 0000 2348 FFD0 0000 FFF0 FFCC FFC8 FFC4 FFC0 FFBC Save $ra 107 © Andrew Hilton / Alvin R. Lebeck Execution example: Calling with frames CPS 104 Reg Value $r0 0000 0000 $at 0000 0000 $v0 4242 4242 $v1 0000 8010 $a0 0000 1234 $a1 5678 0001 $a2 0000 0002 $a3 0000 0007 $t0 9999 999A $t1 0000 0000 $s0 0042 0420 $sp 0000 FFD0 $fp 0000 FFF0 $ra 0000 2348 PC 0000 1010 Addr Instruction 1000 subiu $sp, $sp, 16 1004 sw $fp, 0($sp) 1008 sw $ra, 4($sp) 100C sw $s0, 8($sp) 1010 addiu $fp, $sp, 12 1014 add $s0, $a0, $a1 1018 jal 4200 101C add $t0, $v0, $s0 1020 lw $v0, 4($t0) 1024 lw $s0, -4($fp) 1028 lw $ra, -8($fp) 102C lw $fp, -12($fp) 1030 addiu $sp, $sp, 16 1034 jr $ra Addr Value FFF0 0001 0070 FFEC 1234 5678 FFE8 9999 9999 FFE4 0000 2568 FFE0 0001 0040 FFDC FFD8 0042 0420 FFD4 0000 2348 FFD0 0000 FFF0 FFCC FFC8 FFC4 FFC0 FFBC Save $s0 (caller saves) 108 © Andrew Hilton / Alvin R. Lebeck Execution example: Calling with frames CPS 104 Reg Value $r0 0000 0000 $at 0000 0000 $v0 4242 4242 $v1 0000 8010 $a0 0000 1234 $a1 5678 0001 $a2 0000 0002 $a3 0000 0007 $t0 9999 999A $t1 0000 0000 $s0 0042 0420 $sp 0000 FFD0 $fp 0000 FFDC $ra 0000 2348 PC 0000 1014 Addr Instruction 1000 subiu $sp, $sp, 16 1004 sw $fp, 0($sp) 1008 sw $ra, 4($sp) 100C sw $s0, 8($sp) 1010 addiu $fp, $sp, 12 1014 add $s0, $a0, $a1 1018 jal 4200 101C add $t0, $v0, $s0 1020 lw $v0, 4($t0) 1024 lw $s0, -4($fp) 1028 lw $ra, -8($fp) 102C lw $fp, -12($fp) 1030 addiu $sp, $sp, 16 1034 jr $ra Addr Value FFF0 0001 0070 FFEC 1234 5678 FFE8 9999 9999 FFE4 0000 2568 FFE0 0001 0040 FFDC FFD8 0042 0420 FFD4 0000 2348 FFD0 0000 FFF0 FFCC FFC8 FFC4 FFC0 FFBC Setup $fp 109 © Andrew Hilton / Alvin R. Lebeck Execution example: Calling with frames CPS 104 Reg Value $r0 0000 0000 $at 0000 0000 $v0 4242 4242 $v1 0000 8010 $a0 0000 1234 $a1 5678 0001 $a2 0000 0002 $a3 0000 0007 $t0 9999 999A $t1 0000 0000 $s0 0042 0420 $sp 0000 FFD0 $fp 0000 FFDC $ra 0000 2348 PC 0000 1014 Addr Instruction 1000 subiu $sp, $sp, 16 1004 sw $fp, 0($sp) 1008 sw $ra, 4($sp) 100C sw $s0, 8($sp) 1010 addiu $fp, $sp, 12 1014 add $s0, $a0, $a1 1018 jal 4200 101C add $t0, $v0, $s0 1020 lw $v0, 4($t0) 1024 lw $s0, -4($fp) 1028 lw $ra, -8($fp) 102C lw $fp, -12($fp) 1030 addiu $sp, $sp, 16 1034 jr $ra Addr Value FFF0 0001 0070 FFEC 1234 5678 FFE8 9999 9999 FFE4 0000 2568 FFE0 0001 0040 FFDC FFD8 0042 0420 FFD4 0000 2348 FFD0 0000 FFF0 FFCC FFC8 FFC4 FFC0 FFBC $sp, $fp now describe new frame, ready to start 110 © Andrew Hilton / Alvin R. Lebeck Execution example: Calling with frames CPS 104 Reg Value $r0 0000 0000 $at 0000 0000 $v0 4242 4242 $v1 0000 8010 $a0 0000 1234 $a1 5678 0001 $a2 0000 0002 $a3 0000 0007 $t0 9999 999A $t1 0000 0000 $s0 5678 1235 $sp 0000 FFD0 $fp 0000 FFDC $ra 0000 2348 PC 0000 1018 Addr Instruction 1000 subiu $sp, $sp, 16 1004 sw $fp, 0($sp) 1008 sw $ra, 4($sp) 100C sw $s0, 8($sp) 1010 addiu $fp, $sp, 12 1014 add $s0, $a0, $a1 1018 jal 4200 101C add $t0, $v0, $s0 1020 lw $v0, 4($t0) 1024 lw $s0, -4($fp) 1028 lw $ra, -8($fp) 102C lw $fp, -12($fp) 1030 addiu $sp, $sp, 16 1034 jr $ra Addr Value FFF0 0001 0070 FFEC 1234 5678 FFE8 9999 9999 FFE4 0000 2568 FFE0 0001 0040 FFDC FFD8 0042 0420 FFD4 0000 2348 FFD0 0000 FFF0 FFCC FFC8 FFC4 FFC0 FFBC Do some computation.. 111 © Andrew Hilton / Alvin R. Lebeck Execution example: Calling with frames CPS 104 Reg Value $r0 0000 0000 $at 0000 0000 $v0 4242 4242 $v1 0000 8010 $a0 0000 1234 $a1 5678 0001 $a2 0000 0002 $a3 0000 0007 $t0 9999 999A $t1 0000 0000 $s0 5678 1235 $sp 0000 FFD0 $fp 0000 FFDC $ra 0000 101C PC 0000 4200 Addr Instruction 1000 subiu $sp, $sp, 16 1004 sw $fp, 0($sp) 1008 sw $ra, 4($sp) 100C sw $s0, 8($sp) 1010 addiu $fp, $sp, 12 1014 add $s0, $a0, $a1 1018 jal 4200 101C add $t0, $v0, $s0 1020 lw $v0, 4($t0) 1024 lw $s0, -4($fp) 1028 lw $ra, -8($fp) 102C lw $fp, -12($fp) 1030 addiu $sp, $sp, 16 1034 jr $ra Addr Value FFF0 0001 0070 FFEC 1234 5678 FFE8 9999 9999 FFE4 0000 2568 FFE0 0001 0040 FFDC FFD8 0042 0420 FFD4 0000 2348 FFD0 0000 FFF0 FFCC FFC8 FFC4 FFC0 FFBC Call another function (not pictured, takes no args) jal sets $ra, PC 112 © Andrew Hilton / Alvin R. Lebeck Execution example: Calling with frames CPS 104 Reg Value $r0 0000 0000 $at ???? ???? $v0 ???? ???? $v1 ???? ???? $a0 ???? ???? $a1 ???? ???? $a2 ???? ???? $a3 ???? ???? $t0 ???? ???? $t1 ???? ???? $s0 ???? ???? $sp ???? ???? $fp ???? ???? $ra ???? ???? PC ???? ???? Addr Instruction 1000 subiu $sp, $sp, 16 1004 sw $fp, 0($sp) 1008 sw $ra, 4($sp) 100C sw $s0, 8($sp) 1010 addiu $fp, $sp, 12 1014 add $s0, $a0, $a1 1018 jal 4200 101C add $t0, $v0, $s0 1020 lw $v0, 4($t0) 1024 lw $s0, -4($fp) 1028 lw $ra, -8($fp) 102C lw $fp, -12($fp) 1030 addiu $sp, $sp, 16 1034 jr $ra Addr Value FFF0 0001 0070 FFEC 1234 5678 FFE8 9999 9999 FFE4 0000 2568 FFE0 0001 0040 FFDC FFD8 0042 0420 FFD4 0000 2348 FFD0 0000 FFF0 FFCC FFC8 FFC4 FFC0 FFBC Other function can do what It wants to the regs as it computes And make a stack frame Of its own 113 © Andrew Hilton / Alvin R. Lebeck Execution example: Calling with frames CPS 104 Reg Value $r0 0000 0000 $at ???? ???? $v0 8675 3090 $v1 ???? ???? $a0 ???? ???? $a1 ???? ???? $a2 ???? ???? $a3 ???? ???? $t0 ???? ???? $t1 ???? ???? $s0 5678 1235 $sp 0000 FFD0 $fp 0000 FFDC $ra 0000 101C PC 0000 101C Addr Instruction 1000 subiu $sp, $sp, 16 1004 sw $fp, 0($sp) 1008 sw $ra, 4($sp) 100C sw $s0, 8($sp) 1010 addiu $fp, $sp, 12 1014 add $s0, $a0, $a1 1018 jal 4200 101C add $t0, $v0, $s0 1020 lw $v0, 4($t0) 1024 lw $s0, -4($fp) 1028 lw $ra, -8($fp) 102C lw $fp, -12($fp) 1030 addiu $sp, $sp, 16 1034 jr $ra Addr Value FFF0 0001 0070 FFEC 1234 5678 FFE8 9999 9999 FFE4 0000 2568 FFE0 0001 0040 FFDC FFD8 0042 0420 FFD4 0000 2348 FFD0 0000 FFF0 FFCC FFC8 FFC4 FFC0 FFBC But before it returns, it is responsible for restoring certain registers Including $sp and $fp, and $s0 Value returned in $v0 114 © Andrew Hilton / Alvin R. Lebeck Execution example: Calling with frames CPS 104 Reg Value $r0 0000 0000 $at ???? ???? $v0 8675 3090 $v1 ???? ???? $a0 ???? ???? $a1 ???? ???? $a2 ???? ???? $a3 ???? ???? $t0 DCED 42C5 $t1 ???? ???? $s0 5678 1235 $sp 0000 FFD0 $fp 0000 FFDC $ra 0000 101C PC 0000 1020 Addr Instruction 1000 subiu $sp, $sp, 16 1004 sw $fp, 0($sp) 1008 sw $ra, 4($sp) 100C sw $s0, 8($sp) 1010 addiu $fp, $sp, 12 1014 add $s0, $a0, $a1 1018 jal 4200 101C add $t0, $v0, $s0 1020 lw $v0, 4($t0) 1024 lw $s0, -4($fp) 1028 lw $ra, -8($fp) 102C lw $fp, -12($fp) 1030 addiu $sp, $sp, 16 1034 jr $ra Addr Value FFF0 0001 0070 FFEC 1234 5678 FFE8 9999 9999 FFE4 0000 2568 FFE0 0001 0040 FFDC FFD8 0042 0420 FFD4 0000 2348 FFD0 0000 FFF0 FFCC FFC8 FFC4 FFC0 FFBC Do some more computation 115 © Andrew Hilton / Alvin R. Lebeck Execution example: Calling with frames CPS 104 Reg Value $r0 0000 0000 $at ???? ???? $v0 0001 0002 $v1 ???? ???? $a0 ???? ???? $a1 ???? ???? $a2 ???? ???? $a3 ???? ???? $t0 DCED 42C5 $t1 ???? ???? $s0 5678 1235 $sp 0000 FFD0 $fp 0000 FFDC $ra 0000 101C PC 0000 1024 Addr Instruction 1000 subiu $sp, $sp, 16 1004 sw $fp, 0($sp) 1008 sw $ra, 4($sp) 100C sw $s0, 8($sp) 1010 addiu $fp, $sp, 12 1014 add $s0, $a0, $a1 1018 jal 4200 101C add $t0, $v0, $s0 1020 lw $v0, 4($t0) 1024 lw $s0, -4($fp) 1028 lw $ra, -8($fp) 102C lw $fp, -12($fp) 1030 addiu $sp, $sp, 16 1034 jr $ra Addr Value FFF0 0001 0070 FFEC 1234 5678 FFE8 9999 9999 FFE4 0000 2568 FFE0 0001 0040 FFDC FFD8 0042 0420 FFD4 0000 2348 FFD0 0000 FFF0 FFCC FFC8 FFC4 FFC0 FFBC Do some more computation (load addr not pictured) 116 © Andrew Hilton / Alvin R. Lebeck Execution example: Calling with frames CPS 104 Reg Value $r0 0000 0000 $at ???? ???? $v0 0001 0002 $v1 ???? ???? $a0 ???? ???? $a1 ???? ???? $a2 ???? ???? $a3 ???? ???? $t0 DCED 42C5 $t1 ???? ???? $s0 0042 0420 $sp 0000 FFD0 $fp 0000 FFDC $ra 0000 101C PC 0000 1028 Addr Instruction 1000 subiu $sp, $sp, 16 1004 sw $fp, 0($sp) 1008 sw $ra, 4($sp) 100C sw $s0, 8($sp) 1010 addiu $fp, $sp, 12 1014 add $s0, $a0, $a1 1018 jal 4200 101C add $t0, $v0, $s0 1020 lw $v0, 4($t0) 1024 lw $s0, -4($fp) 1028 lw $ra, -8($fp) 102C lw $fp, -12($fp) 1030 addiu $sp, $sp, 16 1034 jr $ra Addr Value FFF0 0001 0070 FFEC 1234 5678 FFE8 9999 9999 FFE4 0000 2568 FFE0 0001 0040 FFDC FFD8 0042 0420 FFD4 0000 2348 FFD0 0000 FFF0 FFCC FFC8 FFC4 FFC0 FFBC Restore registers to return 117 © Andrew Hilton / Alvin R. Lebeck Execution example: Calling with frames CPS 104 Reg Value $r0 0000 0000 $at ???? ???? $v0 0001 0002 $v1 ???? ???? $a0 ???? ???? $a1 ???? ???? $a2 ???? ???? $a3 ???? ???? $t0 DCED 42C5 $t1 ???? ???? $s0 0042 0420 $sp 0000 FFD0 $fp 0000 FFDC $ra 0000 2348 PC 0000 102C Addr Instruction 1000 subiu $sp, $sp, 16 1004 sw $fp, 0($sp) 1008 sw $ra, 4($sp) 100C sw $s0, 8($sp) 1010 addiu $fp, $sp, 12 1014 add $s0, $a0, $a1 1018 jal 4200 101C add $t0, $v0, $s0 1020 lw $v0, 4($t0) 1024 lw $s0, -4($fp) 1028 lw $ra, -8($fp) 102C lw $fp, -12($fp) 1030 addiu $sp, $sp, 16 1034 jr $ra Addr Value FFF0 0001 0070 FFEC 1234 5678 FFE8 9999 9999 FFE4 0000 2568 FFE0 0001 0040 FFDC FFD8 0042 0420 FFD4 0000 2348 FFD0 0000 FFF0 FFCC FFC8 FFC4 FFC0 FFBC Restore registers to return 118 © Andrew Hilton / Alvin R. Lebeck Execution example: Calling with frames CPS 104 Reg Value $r0 0000 0000 $at ???? ???? $v0 0001 0002 $v1 ???? ???? $a0 ???? ???? $a1 ???? ???? $a2 ???? ???? $a3 ???? ???? $t0 DCED 42C5 $t1 ???? ???? $s0 0042 0420 $sp 0000 FFD0 $fp 0000 FFF0 $ra 0000 2348 PC 0000 1030 Addr Instruction 1000 subiu $sp, $sp, 16 1004 sw $fp, 0($sp) 1008 sw $ra, 4($sp) 100C sw $s0, 8($sp) 1010 addiu $fp, $sp, 12 1014 add $s0, $a0, $a1 1018 jal 4200 101C add $t0, $v0, $s0 1020 lw $v0, 4($t0) 1024 lw $s0, -4($fp) 1028 lw $ra, -8($fp) 102C lw $fp, -12($fp) 1030 addiu $sp, $sp, 16 1034 jr $ra Addr Value FFF0 0001 0070 FFEC 1234 5678 FFE8 9999 9999 FFE4 0000 2568 FFE0 0001 0040 FFDC FFD8 0042 0420 FFD4 0000 2348 FFD0 0000 FFF0 FFCC FFC8 FFC4 FFC0 FFBC Restore registers to return 119 © Andrew Hilton / Alvin R. Lebeck Execution example: Calling with frames CPS 104 Reg Value $r0 0000 0000 $at ???? ???? $v0 0001 0002 $v1 ???? ???? $a0 ???? ???? $a1 ???? ???? $a2 ???? ???? $a3 ???? ???? $t0 DCED 42C5 $t1 ???? ???? $s0 0042 0420 $sp 0000 FFE0 $fp 0000 FFF0 $ra 0000 2348 PC 0000 1034 Addr Instruction 1000 subiu $sp, $sp, 16 1004 sw $fp, 0($sp) 1008 sw $ra, 4($sp) 100C sw $s0, 8($sp) 1010 addiu $fp, $sp, 12 1014 add $s0, $a0, $a1 1018 jal 4200 101C add $t0, $v0, $s0 1020 lw $v0, 4($t0) 1024 lw $s0, -4($fp) 1028 lw $ra, -8($fp) 102C lw $fp, -12($fp) 1030 addiu $sp, $sp, 16 1034 jr $ra Addr Value FFF0 0001 0070 FFEC 1234 5678 FFE8 9999 9999 FFE4 0000 2568 FFE0 0001 0040 FFDC FFD8 0042 0420 FFD4 0000 2348 FFD0 0000 FFF0 FFCC FFC8 FFC4 FFC0 FFBC Restore registers to return 120 © Andrew Hilton / Alvin R. Lebeck Execution example: Calling with frames CPS 104 Reg Value $r0 0000 0000 $at ???? ???? $v0 0001 0002 $v1 ???? ???? $a0 ???? ???? $a1 ???? ???? $a2 ???? ???? $a3 ???? ???? $t0 DCED 42C5 $t1 ???? ???? $s0 0042 0420 $sp 0000 FFE0 $fp 0000 FFF0 $ra 0000 2348 PC 0000 1034 Addr Instruction 1000 subiu $sp, $sp, 16 1004 sw $fp, 0($sp) 1008 sw $ra, 4($sp) 100C sw $s0, 8($sp) 1010 addiu $fp, $sp, 12 1014 add $s0, $a0, $a1 1018 jal 4200 101C add $t0, $v0, $s0 1020 lw $v0, 4($t0) 1024 lw $s0, -4($fp) 1028 lw $ra, -8($fp) 102C lw $fp, -12($fp) 1030 addiu $sp, $sp, 16 1034 jr $ra Addr Value FFF0 0001 0070 FFEC 1234 5678 FFE8 9999 9999 FFE4 0000 2568 FFE0 0001 0040 FFDC FFD8 0042 0420 FFD4 0000 2348 FFD0 0000 FFF0 FFCC FFC8 FFC4 FFC0 FFBC Restore registers to return Now $sp, $fp describe caller’s frame 121 © Andrew Hilton / Alvin R. Lebeck Execution example: Calling with frames CPS 104 Reg Value $r0 0000 0000 $at ???? ???? $v0 0001 0002 $v1 ???? ???? $a0 ???? ???? $a1 ???? ???? $a2 ???? ???? $a3 ???? ???? $t0 DCED 42C5 $t1 ???? ???? $s0 0042 0420 $sp 0000 FFE0 $fp 0000 FFF0 $ra 0000 2348 PC 0000 2348 Addr Instruction 1000 subiu $sp, $sp, 16 1004 sw $fp, 0($sp) 1008 sw $ra, 4($sp) 100C sw $s0, 8($sp) 1010 addiu $fp, $sp, 12 1014 add $s0, $a0, $a1 1018 jal 4200 101C add $t0, $v0, $s0 1020 lw $v0, 4($t0) 1024 lw $s0, -4($fp) 1028 lw $ra, -8($fp) 102C lw $fp, -12($fp) 1030 addiu $sp, $sp, 16 1034 jr $ra Addr Value FFF0 0001 0070 FFEC 1234 5678 FFE8 9999 9999 FFE4 0000 2568 FFE0 0001 0040 FFDC FFD8 0042 0420 FFD4 0000 2348 FFD0 0000 FFF0 FFCC FFC8 FFC4 FFC0 FFBC Return to caller (code not pictured) 122 © Andrew Hilton / Alvin R. Lebeck CPS 104 • System call is used to communicate with the operating system, and request services (memory allocation, I/O) • Load system call code (value) into Register $v0 • Load arguments (if any) into registers $a0, $a1 or $f12 (for floating point). • do: syscall • Results returned in registers $v0 or $f0. • Note: $v0 = $2, $a0=$4, $a1 = $5 System Call Instruction 123 © Andrew Hilton / Alvin R. Lebeck CPS 104 SPIM System Call Support code service Arguments Result 1 print int $a0 2 print float $f12 3 print double $f12 4 print string $a0 (string address) 5 read integer integer in $v0 6 read float float in $f0 7 read double double in $f0 8 read string $a0=buffer, $a1=length 9 sbrk $a0=amount address in $v0 10 exit 124 © Andrew Hilton / Alvin R. Lebeck CPS 104 MIPS Assembly General Rules • One instruction per line. • Numbers are base-10 integers or Hex w/ leading 0x. • Identifiers: alphanumeric, _, . string starting in a letter or _ • Labels: identifiers starting at the beginning of a line followed by “:” • Comments: everything following # till end-of-line. • Instruction format: Space and “,” separated fields. − [Label:] reg1, [reg2], [reg3] [# comment] − [Label:] reg1, offset(reg2) [# comment] − .Directive [arg1], [arg2], . . . 125 © Andrew Hilton / Alvin R. Lebeck CPS 104 Summary • MIPS ISA and Assembly Programming − We’ll use SPIM (or xspim) − Have seen most basic instruction types − See Appendix B for full insn reference • Next time: − A bit deeper into MIPS assembly − Recursion! • Note: − Examples/reference from prior semesters at end of slide deck 126 © Andrew Hilton / Alvin R. Lebeck CPS 104 Which add for address arithmetic? Which for integers? MIPS Arithmetic Instructions Instruction Example Meaning Comments add add $1,$2,$3 $1 = $2 + $3 3 operands subtract sub $1,$2,$3 $1 = $2 – $3 3 operands add immediate addi $1,$2,100 $1 = $2 + 100 + constant add unsigned addu $1,$2,$3 $1 = $2 + $3 3 operands subtract unsigned subu $1,$2,$3 $1 = $2 – $3 3 operands add imm. unsign. addiu $1,$2,100 $1 = $2 + 100 + constant multiply mult $2,$3 Hi, Lo = $2 x $3 64-bit signed product multiply unsigned multu $2,$3 Hi, Lo = $2 x $3 64-bit unsigned product divide div $2,$3 Lo = $2 ÷ $3, Lo = quotient, Hi = $2 mod $3 Hi = remainder divide unsigned divu $2,$3 Lo = $2 ÷ $3, Unsigned quotient Hi = $2 mod $3 Usigned remainder Move from Hi mfhi $1 $1 = Hi Used to get copy of Hi Move from Lo mflo $1 $1 = Lo Used to get copy of Lo 127 © Andrew Hilton / Alvin R. Lebeck CPS 104 MIPS Logical Instructions Instruction Example Meaning Comment and and $1,$2,$3 $1 = $2 & $3 Bitwise AND or or $1,$2,$3 $1 = $2 | $3 Bitwise OR xor xor $1,$2,$3 $1 = $2 ⊕ $3 Bitwise XOR nor nor $1,$2,$3 $1 = ~($2 | $3) Bitwise NOR and immediate andi $1,$2,10 $1 = $2 & 10 Bitwise AND reg, const or immediate ori $1,$2,10 $1 = $2 | 10 Bitwise OR reg, const xor immediate xori $1, $2,10 $1 = ~$2 &~10 Bitwise XOR reg, const shift left logical sll $1,$2,10 $1 = $2 << 10 Shift left by constant shift right logical srl $1,$2,10 $1 = $2 >> 10 Shift right by constant shift right arithm. sra $1,$2,10 $1 = $2 >> 10 Shift right (sign extend) shift left logical sllv $1,$2,$3 $1 = $2 << $3 Shift left by var shift right logical srlv $1,$2, $3 $1 = $2 >> $3 Shift right by var shift right arithm. srav $1,$2, $3 $1 = $2 >> $3 Shift right arith. by var 128 © Andrew Hilton / Alvin R. Lebeck CPS 104 0000 … 0000 LUI R5 R5 MIPS Data Transfer Instructions Instruction Comment SW R3, 500(R4) Store word SH R3, 502(R2) Store half SB R2, 41(R3) Store byte LW R1, 30(R2) Load word LH R1, 40(R3) Load halfword LHU R1, 40(R3) Load halfword unsigned LB R1, 40(R3) Load byte LBU R1, 40(R3) Load byte unsigned LUI R1, 40 Load Upper Immediate (16 bits shifted left by 16) Why do we need LUI? 129 © Andrew Hilton / Alvin R. Lebeck CPS 104 A Simple Program • Add two numbers x & y together .text # declare text segment .align 2 # align it on 4-byte boundary main: # label for main la $3, x # load address of x into R3 (pseudo-inst) lw $4, 0($3) # load value of x into R4 la $7, y # load address of y into R3 (pseudo-inst) lw $5, 0($7) # load value of y into R5 add $6, $4, $5 # compute x+y st $6, 0($3) # store value to x jr $31 # return to calling routine .data # declare data segment .align 2 # align it on 4-byte boundary x: .word 10 # initialize x to 10 y: .word 3 # initialize y to 3 130 © Andrew Hilton / Alvin R. Lebeck Typical Code Segments-IF if (x != y) then x = x + y; # $4 has x $5 has y beq $4, $5, eq # check if x != y add $6, $4, $5 # compute x+y eq: st $6, 0($3) # store value to x jr $31 # return to calling routine CPS 104 131 © Andrew Hilton / Alvin R. Lebeck Typical Code Segments-IF Else if (x != y) then x = x + y; else x = x-y; # $4 has x $5 has y beq $4, $5, eq # check if x != y add $6, $4, $5 # compute x+y b done eq: sub $6, $5, $4 # compute x-y done: st $6, 0($3) # store value to x jr $31 # return to calling routine CPS 104 132 © Andrew Hilton / Alvin R. Lebeck CPS 104 The C code #include int main ( ) { int i; int sum = 0; for(i=0; i <= 100; i++) sum = sum + i*i ; printf(“The answer is %d\n“, sum); } Let’s write the assembly … :) 133 © Andrew Hilton / Alvin R. Lebeck CPS 104 .text .align 2 main: move $14, $0 # i = 0 move $15, $0 # tmp = 0 move $16, $0 # sum = 0 loop: mul $15, $14, $14 # i*i add $16, $16, $15 # sum+i*i addi $14, $14, 1 # i++ ble $14, 100, loop # i < 100 go print answer exit Assembly Language Example 1 134 © Andrew Hilton / Alvin R. Lebeck CPS 104 Echo number and string .text main: li $v0, 5 # code to read an integer syscall # do the read (invokes the OS) move $a0, $v0 # copy result from v0 to a0 li $v0, 1 # code to print an integer syscall # print the integer li $v0, 4 # code to print string la $a0, nln # address of string (newline) syscall 135 © Andrew Hilton / Alvin R. Lebeck CPS 104 Echo Continued li $v0, 8 # code to read a string la $a0, name # address of buffer (name) li $a1, 8 # size of buffer (8 bytes) syscall la $a0, name # address of string to print li $v0, 4 # code to print a string syscall jr $31 # return .data .align 2 name: .word 0,0 nln: .asciiz "\n" 136 © Andrew Hilton / Alvin R. Lebeck CPS 104 Example2 Task: sum together the integers stored in memory .text # Code .align 2 # align on word boundary .globl main # declare main main: # MAIN procedure Entrance # fill in what goes here .data # Start of data segment list: .word 35, 16, 42, 19, 55, 91, 24, 61, 53 msg: .asciiz "The sum is " nln: .asciiz "\n" 137 © Andrew Hilton / Alvin R. Lebeck CPS 104 Example2 # Example for CPS 104 # Program to add together list of 9 numbers. .text # Code .align 2 .globl main main: # MAIN procedure Entrance subu $sp, 40 #\ Push the stack sw $ra, 36($sp) # \ Save return address sw $s3, 32($sp) # \ sw $s2, 28($sp) # > Entry Housekeeping sw $s1, 24($sp) # / save registers on stack sw $s0, 20($sp) # / move $v0, $0 #/ initialize exit code to 0 move $s1, $0 #\ la $s0, list # \ Initialization la $s2, msg # / la $s3, list+36 #/ 138 © Andrew Hilton / Alvin R. Lebeck CPS 104 Example2 (cont.) # Main code segment again: # Begin main loop lw $t6, 0($s0) #\ addu $s1, $s1, $t6 #/ Actual "work" # SPIM I/O li $v0, 4 #\ move $a0, $s2 # > Print a string syscall #/ li $v0, 1 #\ move $a0, $s1 # > Print a number syscall #/ li $v0, 4 #\ la $a0, nln # > Print a string (eol) syscall #/ addu $s0, $s0, 4 #\ index update and bne $s0, $s3, again #/ end of loop 139 © Andrew Hilton / Alvin R. Lebeck CPS 104 Example2 (cont.) # Exit Code move $v0, $0 #\ lw $s0, 20($sp) # \ lw $s1, 24($sp) # \ lw $s2, 28($sp) # \ Closing Housekeeping lw $s3, 32($sp) # / restore registers lw $ra, 36($sp) # / load return address addu $sp, 40 # / Pop the stack jr $ra #/ exit(0) ; .end main # end of program # Data Segment .data # Start of data segment list: .word 35, 16, 42, 19, 55, 91, 24, 61, 53 msg: .asciiz "The sum is " nln: .asciiz "\n"