How To Assign A Char To A Register Mips
C: Assembly Language (MIPS)
| Pedagogy Fix Architectures |
A typical modern CPU has
- a gear up of data registers
- a gear up of control registers (incl PC)
- an arithmetics-logic unit (ALU)
- admission to random access retentivity (RAM)
- a set of elementary instructions
- transfer data between memory and registers
- push button values through the ALU to compute results
- make tests and transfer command of execution
Dissimilar types of processors have different configurations of the above
- e.g. different # registers, different sized registers, different instructions
| Why Study Assembler? | 3/114 |
Useful to know assembly language because ...
- sometimes you are required to utilise information technology (e.g. device handlers)
- improves your understanding of how C programs execute
- very helpful when debugging
- able to avert using known inefficient constructs
- uber-nerdy performance tweaking (squeezing out last nano-due south)
- re-write that disquisitional (frequently-used) function in assembler
Two wide families of instruction set architectures ...
RISC (reduced educational activity set computer)
- small(ish) set of unproblematic, general instructions
- dissever computation & data transfer instructions
- leading to simpler processor hardware
- e.g. MIPS, RISC, Alpha, SPARC, PowerPC, ARM, ...
- large(r) set of powerful instructions
- each instruction has multiple actions (comp+store)
- more than circuitry to decode/process instructions
- e.g. PDP, VAX, Z80, Motorola 68xxx, Intel x86, ...
| ... Instruction Sets | 5/114 |
Machine-level instructions ...
- typically have one-2 32-bit words per teaching
- segmentation bits in each word into operator & operands
- #bits for each depends on #instructions, #registers, ...
Operands and destination are typically registers
| ... Education Sets | half-dozen/114 |
Common kinds of instructions
-
Annalsload MemoryAddress,- copy value stored in retentiveness at address into named register
-
Annalsloadc ConstantValue,- copy value into named register
-
Registershop MemoryAddress,- copy value stored in named register into memory at address
-
MemoryAddressleap- transfer execution of program to instruction at address
-
Annalsjumpif MemoryAddress,- transfer execution of program if east.g. register holds goose egg value
| ... Instruction Sets | 7/114 |
Other mutual kinds of instructions
-
Annalsaneadd together Register2, Register3 (similarly for, ,sub ,mul )div- Annals3 = Register1
Register2+
- Annals3 = Register1
-
Annals1and Register2, Registerthree (similarly for, ,or )xor- Register3 = Register1
Annals2&
- Register3 = Register1
-
Annals1neg Annalstwo,- Annalsii =
Annals1~
- Annalsii =
-
Annals1shiftl Value, Annals2 (similarly for, )shiftr- Register2 = Annalsone
Value<<
- Register2 = Annalsone
-
Valuesyscall- invoke a system service; which service adamant by Value
| ... Instruction Sets | 8/114 |
All CPUs have programme execution logic like:
while (1) { instruction = memory[PC] PC++ // move to next instr if (instruction == HALT) intermission else execute(teaching) }
PC = Program Counter, a CPU register which keeps rails of execution
Note that some instructions may alter PC further (eastward.g. JUMP)
| ... Fetch-Execute Bike | ten/114 |
Executing an pedagogy
- decide what the operator is
- decide which registers, if any, are involved
- determine which retentiveness location, if any, is involved
- deport out the operation with the relevant operands
- shop result, if any, in appropriate annals
Instructions are only scrap patterns within a 32-bit bit-string
Could draw motorcar programs as a sequence of hex digits, e.grand.
Address Content 0x100000 0x3c041001 0x100004 0x34020004 0x100008 0x0000000c 0x10000C 0x03e00008
Often call "assembly language" every bit "assembler"
Slight notational abuse, because "assembler" besides refers to a program that translates assembly language to auto code
| ... Assembly Language | 12/114 |
Assembler = symbolic language for writing machine lawmaking
- write instructions using mnemonics rather than hex codes
- reference registers using either numbers or names
- tin can associate names to memory addresses
Style of expression is significantly unlike to eastward.chiliad. C
- need to use fine-grained control of memory usage
- required to manipulate information in registers
- control structures programmed via explicit jumps
MIPS is a well-known and relatively simple architecture
- very pop in a range of computing devices in the 1990's
- due east.yard. Silicon Graphics, NEC, Nintendo64, Playstation, supercomputers
- using ii variants of the open up-source SPIM emulator
-
... provides a GUI forepart-terminate, useful for debuggingqtspim -
... command-line based version, useful for testingspim -
... GUI front-end, useful for debugging, simply in CSE labsxspim
Source code for browsing under /habitation/cs1521/spim/spim
MIPS is a automobile compages, including educational activity prepare
SPIM is an emulator for the MIPS education set
- reads text files containing instruction + directives
- converts to machine code and loads into "memory"
- provides debugging capabilities
- single-pace, breakpoints, view registers/retentivity, ...
- provides mechanism to interact with operating organisation (syscall)
- provide convenient/mnemonic ways to exercise common operations
- east.1000.
rather thanmove $s0,$v0addu $s0,$0,$v0
3 ways to execute MIPS code with SPIM
-
... command line toolspim- load programs using
option-file - interact using stdin/stdout via login terminal
- load programs using
-
... GUI environmentqtspim- load programs via a load button
- interact via a pop-upward stdin/stdout final
-
... GUI environmentxspim- like to
, but not as prettyqtspim - requires X-windows server
- like to
Control-line tool:
GUI tool:
| MIPS Machine Archtecture | 18/114 |
MIPS CPU has
- 32 × 32-bit general purpose registers
- 16 × 64-bit double-precision registers
- PC ... 32-scrap register (ever aligned on 4-byte boundary)
- HI,LO ... for storing results of multiplication and division
$0..$31 Some registers take special uses e.thou.
- register
always has value 0, cannot be written$0 - registers
,$1 ,$26 reserved for utilise by arrangement$27
| ... MIPS Car Archtecture | xix/114 |
Registers and their usage
| Reg | Name | Notes | ||
$0 | zero | the value 0, non changeable | ||
$1 | $at | assembler temporary; used to implement pseudo-ops | ||
$two | $v0 | value from expression evaluation or function return | ||
$three | $v1 | value from expression evaluation or function return | ||
$4 | $a0 | first argument to a role/subroutine, if needed | ||
$5 | $a1 | second argument to a function/subroutine, if needed | ||
$6 | $a2 | third argument to a function/subroutine, if needed | ||
$7 | $a3 | fourth argument to a role/subroutine, if needed | ||
$eight $15 | $t0 $t7 | temporary; must exist saved by caller to subroutine; subroutine can overwrite |
| ... MIPS Motorcar Archtecture | 20/114 |
More register usage ...
| Reg | Proper name | Notes | ||
$16 | $s0 $s7 | southwardafe office variable; must non be overwritten by called subroutine | ||
$24 $25 | $t8 $t9 | temporary; must exist saved by caller to subroutine; subroutine can overwrite | ||
$26 $27 | $k0 $k1 | for kernel use; may modify unexpectedly | ||
$28 | $gp | global pointer | ||
$29 | $sp | southwardtack pointer | ||
$30 | $fp | frame pointer | ||
$31 | $ra | return address of most recent caller |
| ... MIPS Motorcar Archtecture | 21/114 |
Floating point register usage ...
| Reg | Notes | |
$f0 $f2 | hold floating-point function results | |
$f4 $f10 | temporary registers; not preserved across role calls | |
$f12 $f14 | used for first 2 double-precision function arguments | |
$f16 $f18 | temporary registers; used for expression evaluation | |
$f20 $f30 | saved registers; value is preserved across role calls |
Notes:
- registers come in pairs of 2 × 32-bits
- merely even registers are addressed for double-precision
| MIPS Associates Language | 22/114 |
MIPS assembly language programs comprise
- comments ... introduced past
# - labels ... appended with
: - directives ... symbol kickoff with
. - assembly language instructions
- information objects that live in the data region
- functions (instruction sequences) that live in the code/text region
| ... MIPS Assembly Language | 23/114 |
Example MIPS assembler program:
# hello.southward ... print "Hello, MIPS" .data# the information segment msg: .asciiz "Hello, MIPS\north" .text# the code segment .globl primary main: la $a0, msg# load the argument cord li $v0, iv# load the system call (impress) syscall# print the cord jr $ra# return to caller (__start)
Color coding: label, directive, comment
| ... MIPS Assembly Language | 24/114 |
Generic structure of MIPS programs
# Prog.southward ... annotate giving clarification of part # Author ... .data# variable declarations follow this line # ... .text# instructions follow this line .globl primary main:# indicates start of code # (i.eastward. start user instruction to execute) # ... # Terminate of plan; leave a blank line to make SPIM happy
| ... MIPS Associates Language | 25/114 |
Another example MIPS assembler program:
.data a: .word 42# int a = 42; b: .space four# int b; .text .globl main primary: lw $t0, a# reg[t0] = a li $t1, 8# reg[t1] = viii add $t0, $t0, $t1# reg[t0] = reg[t0]+reg[t1] li $t2, 666# reg[t2] = 666 mult $t0, $t2# (Lo,Hi) = reg[t0]*reg[t2] mflo $t0# reg[t0] = Lo sw $t0, b# b = reg[t0] ....
| ... MIPS Associates Language | 26/114 |
MIPS programs assume the following memory layout
| Region | Address | Notes | ||
| text | 0x00400000 | contains but instructions; read-only; cannot expand | ||
| data | 0x10000000 | data objects; readable/writeable; tin exist expanded | ||
| stack | 0x7fffefff | grows downwardly from that address; readable/writeable | ||
| k_text | 0x80000000 | kernel lawmaking; read-only; only accessible kernel mode | ||
| k_data | 0x90000000 | kernel data; read/write; only accessible kernel mode |
MIPS has several classes of instructions:
- load and store .. transfer information between registers and memory
- computational ... perform arithmetics/logical operations
- bound and branch ... transfer control of program execution
- coprocessor ... standard interface to diverse co-processors
- special ... miscellaneous tasks (e.thousand. syscall)
- between retention and register (direct, indirect)
- constant to annals (immediate)
- register + annals + destination register
| ... MIPS Instructions | 28/114 |
MIPS instructions are 32-bits long, and specify ...
- an performance (eastward.g. load, shop, add, branch, ...)
- one or more operands (e.grand. registers, retentiveness addresses, constants)
Memory addresses tin be given by
- symbolic name (label) (effectively, a constant)
- indirectly via a register (effectively, arrow dereferencing)
prog: a: lw $t0, var# address via proper noun b: lw $t0, ($s0)# indirect addressing c: lw $t0, 4($s0)# indexed addressing
If $s0 0x10000000 &var 0x100000008
- computed accost for
isa:0x100000008 - computed accost for
isb:0x100000000 - computed accost for
isc:0x100000004
| ... Addressing Modes | 30/114 |
Addressing modes in MIPS
| Format | Address ciphering | |
| (annals) | accost = *register = contents of register | |
| chiliad | address = k | |
| k(annals) | accost = k + *annals | |
| symbol | address = &symbol = address of symbol | |
| symbol ± k | address = &symbol ± k | |
| symbol ± k(register) | address = &symbol ± (m + *register) |
where thou is a literal abiding value (east.thousand. 4 0x10000000
| ... Addressing Modes | 31/114 |
Examples of load/store and addressing:
.data vec: .space 16# int vec[4], 16 bytes of storage .text __start: la $t0, vec# reg[t0] = &vec li $t1, 5# reg[t1] = five sw $t1, ($t0)# vec[0] = reg[t1] li $t1, 13# reg[t1] = 13 sw $t1, 4($t0)# vec[ane] = reg[t1] li $t1, -7# reg[t1] = -vii sw $t1, 8($t0)# vec[2] = reg[t1] li $t2, 12# reg[t2] = 12 li $t1, 42# reg[t1] = 42 sw $t1, vec($t2)# vec[three] = reg[t1]
MIPS instructions can manipulate dissimilar-sized operands
- unmarried bytes, two bytes ("halfword"), four bytes ("discussion")
Leads to many opcodes for a (conceptually) single operation, due east.g.
-
... load one byte from specified addressLB -
... load unsigned byte from specified accostLBU -
... load two bytes from specified addressLH -
... load unsigned 2-bytes from specified addressLHU -
... load 4 bytes (one word) from specified addressLW -
... load the specified accostLA
| MIPS Instruction Set | 33/114 |
The MIPS processor implements a base of operations gear up of instructions, east.thousand.
-
,lw ,sw ,add ,sub ,and ,or ,sll ,slt ,beq ,j , ...jal
-
,move ,rem ,la ,li , ...blt
Pseudo-educational activity Base education(south) li $t5, const ori $t5, $0, const la $t3, label lui $at, &label[31..xvi] ori $t3, $at, &label[15..0] bge $t1, $t2, label slt $at, $t1, $t2 beq $at, $0, label blt $t1, $t2, label slt $at, $t1, $t2 bne $at, $0, label
Note: use of $at
| ... MIPS Instruction Set | 34/114 |
In describing instructions:
| Syntax | Semantics |
| $Reg | as source, the content of the register, reg[Reg] |
| $Reg | every bit destination, value is stored in register, reg[Reg] = value |
| Label | references the associated address (in C terms, &Label) |
| Addr | any expression that yields an address (e.g. Label($Reg)) |
| Addr | as source, the content of memory cellmemory[Addr] |
| Addr | as destination, value is stored inmemory[Addr] = value |
Effectively ...
- treat registers asunsigned int reg[32]
- care for memory asunsigned char mem[two32]
| ... MIPS Instruction Ready | 35/114 |
Examples of data movement instructions:
la $t1,label# reg[t1] = &characterization lw $t1,label# reg[t1] = memory[&label] sw $t3,label# memory[&label] = reg[t3] # &label must be four-byte aligned lb $t2,characterization# reg[t2] = retentiveness[&characterization] sb $t4,label# memory[&characterization] = reg[t4] move $t2,$t3# reg[t2] = reg[t3] lui $t2,const# reg[t2][31:16] = const
Examples of fleck manipulation instructions:
and $t0,$t1,$t2# reg[t0] = reg[t1] & reg[t2] and $t0,$t1,Imm# reg[t0] = reg[t1] & Imm[t2] # Imm is a abiding (immediate) or $t0,$t1,$t2# reg[t0] = reg[t1] | reg[t2] xor $t0,$t1,$t2# reg[t0] = reg[t1] ^ reg[t2] neg $t0,$t1# reg[t0] = ~ reg[t1]
| ... MIPS Teaching Gear up | 36/114 |
Examples of arithmetic instructions:
add $t0,$t1,$t2# reg[t0] = reg[t1] + reg[t2] # add equally signed (ii's complement) ints sub $t2,$t3,$t4# reg[t2] = reg[t3] + reg[t4] addi $t2,$t3, 5# reg[t2] = reg[t3] + 5 # "add immediate" (no sub firsthand) addu $t1,$t6,$t7# reg[t1] = reg[t6] + reg[t7] # add every bit unsigned integers subu $t1,$t6,$t7# reg[t1] = reg[t6] + reg[t7] # subtract every bit unsigned integers mult $t3,$t4# (Hi,Lo) = reg[t3] * reg[t4] # shop 64-bit result in registers Hello,Lo div $t5,$t6# Lo = reg[t5] / reg[t6] (integer quotient) # Hi = reg[t5] % reg[t6] (remainder) mfhi $t0# reg[t0] = reg[Hello] mflo $t1# reg[t1] = reg[Lo] # used to get effect of MULT or DIV
| ... MIPS Didactics Set up | 37/114 |
Examples of testing and branching instructions:
seq $t7,$t1,$t2# reg[t7] = 1 if (reg[t1]==reg[t2]) # reg[t7] = 0 otherwise (signed) slt $t7,$t1,$t2# reg[t7] = 1 if (reg[t1] < reg[t2]) # reg[t7] = 0 otherwise (signed) slti $t7,$t1,Imm# reg[t7] = ane if (reg[t1] < Imm) # reg[t7] = 0 otherwise (signed) j label# PC = &label jr $t4# PC = reg[t4] beq $t1,$t2,label# PC = &label if (reg[t1] == reg[t2]) bne $t1,$t2,label# PC = &characterization if (reg[t1] != reg[t2]) bgt $t1,$t2,label# PC = &label if (reg[t1] > reg[t2]) bltz $t2,label# PC = &label if (reg[t2] < 0) bnez $t3,label# PC = &label if (reg[t3] != 0)
Later on each co-operative didactics, execution continues at new PC location
| ... MIPS Educational activity Set | 38/114 |
Special jump instruction for invoking functions
jal label# brand a subroutine phone call # save PC in $ra, fix PC to &label # utilise $a0,$a1 equally params, $v0 as return
| ... MIPS Pedagogy Prepare | 39/114 |
SPIM interacts with stdin/stdout via syscall
| Service | Code | Arguments | Result |
| print_int | ane | $a0 = integer | |
| print_float | 2 | $f12 = float | |
| print_double | 3 | $f12 = double | |
| print_string | 4 | $a0 = char * | |
| read_int | 5 | integer in $v0 | |
| read_float | 6 | float in $f0 | |
| read_double | 7 | double in $f0 | |
| read_string | 8 | $a0 = buffer, $a1 = length | string in buffer (including "\northward\0") |
| ... MIPS Educational activity Set | twoscore/114 |
Directives (instructions to assembler, non MIPS instructions)
.text# following instructions placed in text .data# following objects placed in information .globl# make symbol bachelor globally a: .space 18# uchar a[18]; or uint a[four]; .align ii# align next object on 2ii-byte addr i: .word 2# unsigned int i = two; v: .word i,3,5# unsigned int five[3] = {1,3,5}; h: .one-half 2,iv,6# unsigned short h[3] = {2,iv,six}; b: .byte 1,2,3# unsigned char b[3] = {1,ii,3}; f: .float 3.14# float f = iii.14; due south: .asciiz "abc"# char s[4] {'a','b','c','\0'}; t: .ascii "abc"# char s[3] {'a','b','c'};
Writing straight in MIPS assembler is difficult (impossible?)
Strategy for producing likely correct MIPS code
- develop the solution in C
- map to "simplified" C
- interpret each simplified C statement to MIPS instructions
- does non have
,while , complex expressionsswitch - does have simple
,if , ane-operator expressionsgoto - does not have function calls and auto local variables
- does accept jump-and-remember-where-you-came-from
| ... MIPS Programming | 42/114 |
Example translating C to MIPS:
C Simplified C MIPS Assembler ------------ ------------ -------------- int x = five; int ten = 5; x: .discussion v int y = iii; int y = 3; y: .word three int z; int z; z: .space iv int t; lw $t0, 10 lw $t1, y z = 5*(x+y); t = ten+y; add $t0, $t0, $t1 li $t1, 5 t = five*t; mul $t0, $t0, $t1 z = t; sw $t0, z
| ... MIPS Programming | 43/114 |
Simplified C makes extensive use of
- labels ... symbolic proper noun for C statement
- goto ... transfer control to labelled statement
Standard C Simplified C ------------------ ------------------ i = 0; n = 0; i = 0; due north = 0; while (i < v) { loop: north = n + i; if (i >= 5) goto end; i++; northward = n + i; } i++; goto loop; stop:
| ... MIPS Programming | 44/114 |
Beware: registers are shared by all parts of the lawmaking.
Ane function can overwrite value set by another office
int x;// commencement global variable int y;// second global variable int main(void) int f(int n) { { 10 = five; y = 1; y = f(10); for (10 = ane; ten <= n; x++) printf("...",10,y); y = y * x; return 0; return y; } }
After the role, x == half dozen y == 120
It is sheer coincidence that y
| ... MIPS Programming | 45/114 |
Demand to be careful managing registers
- follow the conventions implied by register names
- preserve values that need to be saved across function calls
- yous manage annals usage every bit you like
- typically making use of
registers$t?
- you transfer control to a separate slice of code
- which may alter the value of any non-preserved register
-
registers must be preserved past function$s? -
,$a? ,$v? registers may exist modified past function$t?
| Rendering C in MIPS | 46/114 |
C provides expression evaluation and consignment, e.g.
-
...x = (1 + y*y) / 2; z = i.0 / 2;
-
,move Rd,Rdue south ,li Rd,Const ,add ,div , ...and
- sequence (
),; ,if ,while ,for ,break , ...go along
-
,seq ,slti , ...,sltu ,beq ,bgtz , ...,bgezal ,j ,jr , ...jal
Sequence is like shooting fish in a barrel Due south1 ; S2 mips(Sone) mips(S2)
| ... Rendering C in MIPS | 47/114 |
Elementary case of assignment and sequence:
int x; x: .space 4 int y; y: .infinite 4 x = 2; li $t0, 2 sw $t0, 10 y = x; lw $t0, ten sw $t0, y y = x+3; lw $t0, x addi $t0, 3 sw $t0, y
| Arithmetics Expressions | 48/114 |
Expression evaluation involves
- describing the procedure as a sequence of binary operations
- managing data flow between the operations
# ten = (ane + y*y) / 2 lw $t0, y mul $t0, $t0, $t0 addi $t0, $t0, one li $t1, 2 div $t0, $t1 mflo $t0 sw $t0, ten
It is useful to minimise the number of registers involved in the evaluation
| Conditional Statements | 49/114 |
Conditional statements (e.g. if
Standard C Simplified C ------------------------ ------------------------ if_stat: if (Cond) t0 = (Cond) { Statements1 } if (t0 == 0) else goto else_part; { Statementsii } Statements1 goto end_if; else_part: Statementstwo end_if:
| ... Conditional Statements | 50/114 |
Conditional statements (due east.g. if
if_stat: if (Cond) t0 = evaluate (Cond) { Statements1 } beqz $t0, else_part else execute Statementsi { Statementsii } j end_if else_part: execute Statementsii end_if:
| ... Provisional Statements | 51/114 |
Example of if-then-else:
int ten; ten is $t0 int y; y is $t1 char z; z is $a0 x = getInt(); li $v0, five syscall move $t0, $v0 y = getInt(); li $v0, 5 syscall motility $t1, $v0 if (ten == y) bne $t0, $t1, printN z = 'Y'; setY: li $a0, 'Y' j impress else setN: z = 'N'; li $a0, 'N' j print# redundant print: putChar(z); li $v0, xi syscall
| ... Conditional Statements | 52/114 |
Could make switch if
switch (Expr) { tmp = Expr; instance Valone: if (tmp == Val1) Statements1 ; break; { Statements1; } case Val2: else if (tmp == Val2 instance Valiii: || tmp == Valiii example Val4: || tmp == Val4) Statements2 ; interruption; { Statements2; } case Val5: else if (tmp == Valv) Statements3 ; interruption; { Statements3; } default: else Statements4 ; pause; { Statements4; } }
| ... Provisional Statements | 53/114 |
Jump table: an alternative implementation of switch
- works best for minor, dense range of case values (e.g. ane..10)
jump_tab: .word c1, c2, c2, c2, c3 switch: t0 = evaluate Expr switch (Expr) { if (t0 < i || t0 > 5) instance 1: jump to default Statements1 ; break; dest = jump_tab[(t0-1)*4] case ii: jump to dest case 3: c1: execute Statements1 case 4: bound to end_switch Statements2 ; break; c2: execute Statementstwo instance 5: jump to end_switch Statements3 ; break; c3: execute Statements3 default: jump to end_switch Statements4 ; break; default: } execute Statementsiv end_switch:
| Boolean Expressions | 54/114 |
Boolean expressions in C are short circuit
(Condane && Cond2 && ... && Condn)
Evaluates by
- evaluate
; if 0 then return 0 for whole expressionCond1 - evaluate
; if 0 then return 0 for whole expressionCond2 - ...
- evaluate
; if 0 then return 0 for whole expressionCondn - otherwise, return 1
C99 standard defines return value for booleans expressions equally 0 or ane
| ... Boolean Expressions | 55/114 |
Similarly for disjunctions
(Cond1 || Condii || ... || Condnorth)
Evaluates by
- evaluate
; if !0 so return 1 for whole expressionCond1 - evaluate
; if !0 and then return one for whole expressionCondtwo - ...
- evaluate
; if !0 then return 1 for whole expressionCondn - otherwise, render 1
C99 standard defines render value for booleans expressions as 0 or 1
| Iteration Statements | 56/114 |
Iteration (east.g. while
top_while: while (Cond) { t0 = evaluate Cond Statements; beqz $t0,end_while } execute Statements j top_while end_while:
Treat for while
i = 0 for (i = 0; i < Northward; i++) { while (i < North) { Statements; Statements; } i++; }
| ... Iteration Statements | 57/114 |
Example of iteration over an array:
int sum, i; sum: .word 4 int a[5] = {1,3,5,7,9}; a: .discussion 1,three,5,7,9 ... ... sum = 0; li $t0, 0 li $t1, 0 li $t2, iv for (i = 0; i < N; i++) for: bgt $t0, $t2, end_for move $t3, $t0 mul $t3, $t3, 4 sum += a[i]; add $t1, $t1, a($t3) printf("%d",sum); addi $t0, $t0, 1 j for end_for: sw $t1, sum move $a0, $t1 li $v0, 1 syscall When nosotros call a function:
- the arguments are evaluated and set upwardly for function
- command is transferred to the code for the part
- local variables are created
- the function lawmaking is executed in this environment
- the render value is set up
- control transfers dorsum to where the office was called from
- the caller receives the render value
Data associated with function calls is placed on the MIPS stack.
Each part allocates a pocket-sized section of the stack (a frame)
- used for: saved registers, local variables, parameters to callees
- created in the function prologue (pushed)
- removed in the function epilogue (popped)
Why we use a stack:
- function
callsf() which callsg()h() -
runs, and so finishes and returns toh()g() -
continues, then finishes and returns togrand()f()
How stack changes as functions are called and return:
Register usage conventions when f() g()
- caller saved registers (saved by
)f()-
tellsf() "If there is anything I want to preserve in these registers, I have already saved it before calling yous"g() -
tellsg() "Don't assume that these registers will be unchanged when I render to you"f() - due east.one thousand.
..$t0 ,$t9 ..$a0 ,$a3$ra
-
- callee saved registers (saved by
)g()-
tellsf() "I presume the values of these registers will be unchanged when you return"1000() -
tellsg() "If I demand to use these registers, I volition save them first and restore them before returning"f() - eastward.g.
..$s0 ,$s7 ,$sp$fp
-
Contents of a typical stack frame:
| Aside: MIPS Branch Delay Slots | 64/114 |
The real MIPS architecture is "pipelined" to better efficiency
- one instruction tin can outset before the previous i finishes
jal - didactics following branch is executed earlier branch completes
nop A problem scenario, and its solution (branch delay slot):
# Implementation of print(compute(42)) li $a0, 42 li $a0, 42 jal compute jal compute move $a0, $v0 nop jal print motion $a0,$v0 jal impress Since SPIM is not pipelined, the nop
| Aside: Why practise we need both $fp and $sp? | 65/114 |
During execution of a function
-
tin alter (e.g. pushing params, adding local vars)$sp - may demand to reference local vars on the stack
- useful if they can be divers by an offset relative to stock-still betoken
-
provides a fixed indicate during role lawmaking execution$fp
int f(int x) { int y = 0; // y created in prologue for (int i = 0; i < 10; i++) // i created in for-loop y += i; // which changes $sp return y; }
| Part Calling Protocol | 66/114 |
Before one office calls some other, information technology needs to
- place 64-bit double args in
and$f12$f14 - place 32-bit arguments in the
..$a0$a3 - if more than four args, or args larger than 32-bits ...
- push value of all such args onto stack
- relieve whatsoever non-
registers that need to be preserved$s?- push value of all such registers onto stack
-
address of function (normally given past a label)jal
$t0 addi $sp, $sp, -four sw $t0, ($sp)
| ... Function Calling Protocol | 67/114 |
Instance: simple function telephone call
int principal() { // x is $s0, y is $s1, z is $s2 int x = five; int y = 7; int z; ... z = sum(x,y,30); ... } int sum(int a, int b, int c) { return a+b+c; }
| ... Function Calling Protocol | 68/114 |
Simple function phone call:
| ... Role Calling Protocol | 69/114 |
Execution of sum()
| ... Role Calling Protocol | 70/114 |
Example: function f() g(a,b,c,d,e,f)
int f(...) { int a,b,c,d,e,f; ... a = g(a,b,c,d,e,f); ... } int thousand(int u,v,w,10,y,z) { return u+v+westward*w*x*y*z; }
| ... Function Calling Protocol | 71/114 |
Function call in MIPS:
| ... Function Calling Protocol | 72/114 |
Execution of chiliad()
| Structure of Functions | 73/114 |
Functions in MIPS have the following general structure:
# outset of function FuncName: # function prologue # prepare stack frame ($fp, $sp) # save relevant registers (incl. $ra) ... # part body # perform computation using $a0, etc. # leaving issue in $v0 ... # function epilogue # restore saved registers (esp. $ra) # clean up stack frame ($fp, $sp) jr $ra
Aim of prologue: create environment for function to execute in.
Before a part starts working, it needs to ...
- create a stack frame for itself (change
and$fp )$sp - save the return address (
) in the stack frame$ra - save any
registers that it plans to change$due south?
- 4 bytes for saved
+ iv bytes for saved$fp$ra - + 4 bytes for each saved
$southward?
$fp $sp - new
= old$fp - four$sp - new
= old$sp - size of frame (in bytes)$sp
| ... Function Prologue | 75/114 |
Example of function fx() $s0 $s1 $s2
| ... Function Prologue | 76/114 |
Alternatively ... (more explicit push
| ... Function Prologue | 77/114 |
Alternatively ... (relative to new $fp
Before a function returns, it needs to ...
- place the return value in
(and maybe$v0 )$v1 - popular any pushed arguments off the stack
- restore the values of whatsoever saved
registers$s? - restore the saved value of
(return accost)$ra - remove its stack frame (change
and$fp )$sp - return to the calling function (
)jr $ra
$fp Changing $fp $sp
- new
= onetime$sp + four$fp - new
=$fp oldmemory[$fp]
| ... Function Epilogue | 79/114 |
Instance of function fx() $s0 $s1 $s2
| Data Structures and MIPS | 80/114 |
C data structures and their MIPS representations:
-
... as byte in memory, or low-order byte in registerchar -
... as word in memory, or whole annalsint -
... as ii-words in memory, ordouble register$f? - arrays ... sequence of memory bytes/words, accessed past index
- structs ... chunk of memory, accessed by fields/offsets
- linked structures ... struct containing address of another struct
char int double - could be implemented in register if used in pocket-sized scope
- could be implemented on stack if local to function
- could be implemented in
if need longer persistence.data
| Static vs Dynamic Allocation | 81/114 |
Static allotment:
- uninitialised memory allocated at compile/gather-time, e.yard.
int val; val: .infinite 4 char str[20]; str: .infinite 20 int vec[20]; vec: .space eighty
- initialised memory allocated at compile/assemble-time, e.one thousand.
int val = five; val: .word five int arr[4] = {9,8,7,6}; arr: .word 9, 8, 7, vi char *msg = "Hello\n"; msg: .asciiz "Hello\north"
| ... Static vs Dynamic Allocation | 82/114 |
Dynamic allocation (i):
- variables local to a function
- use space allocated on stack during part prologue
- referenced during function relative to
$fp - space reclaimed from stack in role epilogue
int fx(int a[]) { int i, j, max; i = 1; j = two; max = i+j; ... }
| ... Static vs Dynamic Allocation | 83/114 |
Example of local variables on the stack:
| ... Static vs Dynamic Resource allotment | 84/114 |
Dynamic allocation (ii):
- uninitialised cake of memory allocated at run-time
int *ptr = malloc(sizeof(int)); char *str = malloc(20*sizeof(char)); int *vec = malloc(20*sizeof(int)); *ptr = five; strcpy(str, "a cord"); vec[0] = 1;
// or *vec = one; vec[i] = 6; - initialised block of memory allocated at run-time
int *vec = calloc(20, sizeof(int));
// vec[i] == 0, for i in 0..19
| ... Static vs Dynamic Allocation | 85/114 |
SPIM doesn't provide malloc() free()
- simply provides
ix to extendsyscall.information - before
, gear upsyscall to the number of bytes requested$a0 - later on
,syscall holds start address of allocated clamper$v0
li $a0, 20# $v0 = malloc(20) li $v0, 9 syscall move $s0, $v0# $s0 = $v0
Cannot admission allocated data by name; need to retain address.
No mode to free allocated data, and no way to align data appropriately
| ... Static vs Dynamic Allocation | 86/114 |
Implementing C-similar malloc() free()
- a complete implementation of C's heap management, i.e.
- a big region of memory to manage (
9)syscall - power to mark chunks of this region as "in utilize" (with size)
- ability to maintain listing of complimentary chunks
- ability to merge free chunks to prevent fragmentation
Can be named/initialised as noted in a higher place:
vec: .space 40# could exist either int vec[10] or char vec[xl] nums: .word 1, iii, v, 7, ix# int nums[6] = {1,3,five,seven,9}
Tin access elements via index or cursor (arrow)
- either approach needs to account for size of elements
- must besides pass assortment size, since not bachelor elsewhere
sumOf()
| ... i-d Arrays in MIPS | 88/114 |
Scanning across an assortment of N
# int vec[10] = {...}; # int i; # for (i = 0; i < 10; i++) # printf("%d\n", vec[i]); li $s0, 0# i = 0 li $s1, 10# no of elements li $s2, 4# sizeof each element loop: bge $s0, $s1, end_loop# if (i >= ten) interruption mul $t0, $s0, $s2# index -> byte start lw $a0, vec($t0)# a0 = vec[i] jal print# print a0 addi $s0, $s0, 1# i++ j loop end_loop:
Assumes the existence of a print() printf("%d\n",10)
| ... 1-d Arrays in MIPS | 89/114 |
Scanning beyond an array of N
# int vec[10] = {...}; # int *cur, *finish = &vec[10]; # for (cur = vec; cur < end; cur++) # printf("%d\n", *cur); la $s0, vec# cur = &vec[0] la $s1, vec+40# cease = &vec[10] loop: bge $s0, $s1, end_loop# if (cur >= end) interruption lw $a0, ($s0)# a0 = *cur jal impress# print a0 addi $s0, $s0, four# cur++ j loop end_loop:
Assumes the being of a print() printf("%d\northward",x)
| ... ane-d Arrays in MIPS | 90/114 |
Arrays that are local to functions are allocated infinite on the stack
fun: int fun(int x)# prologue { addi $sp, $sp, -4 sw $fp, ($sp) move $fp, $sp addi $sp, $sp, -4 sw $ra, ($sp) // push button a[] onto stack addi $sp, $sp, -40 int a[10]; move $s0, $sp int *s0 = a;# office trunk ... compute ... // compute using s0# epilogue // to admission a[] addi $sp, $sp, forty // pop a[] off stack lw $ra, ($sp) addi $sp, $sp, iv lw $fp, ($sp) addi $sp, $sp, 4 jr $ra }
2-d arrays could be represented ii ways:
| ... 2-d Arrays in MIPS | 92/114 |
Representations ofint matrix[4][4]
# for strategy (a) matrix: .space 64# for strategy (b) row0: .space 16 row1: .infinite 16 row2: .infinite 16 row3: .infinite 16 matrix: .discussion row0, row1, row2, row3
Now consider summing all elements
int i, j, sum = 0; for (i = 0; i < 4; i++) for (j = 0; j < 4; j++) sum += matrix[i][j];
| ... two-d Arrays in MIPS | 93/114 |
Accessing elements:
| ... ii-d Arrays in MIPS | 94/114 |
Calculating sum of all elements for strategy (a)int matrix[4][four]
li $s0, 0# sum = 0 li $s1, 4# s1 = 4 (and sizeof int) li $s2, 0# i = 0 li $s3, 16# sizeof row in bytes loop1: beq $s2, $s1, end1# if (i >= 4) break li $s3, 0# j = 0 loop2: beq $s3, $s1, end2# if (j >= 4) break mul $t0, $s2, $s3# off = iv*4*i + 4*j mul $t1, $s3, $s1# matrix[i][j] is add $t0, $t0, $t1# done equally *(matrix+off) lw $t0, matrix($t0)# t0 = matrix[i][j] add $s0, $s0, $t0# sum += t0 addi $s3, $s3, ane# j++ j loop2 end2: addi $s2, $s2, i# i++ j loop1 end1:
| ... ii-d Arrays in MIPS | 95/114 |
Computing sum of all elements for strategy (b)int matrix[four][4]
li $s0, 0# sum = 0 li $s1, 4# s1 = 4 (sizeof(int)) li $s2, 0# i = 0 loop1: beq $s2, $s1, end1# if (i >= 4) suspension li $s3, 0# j = 0 mul $t0, $s2, $s1# off = 4*i lw $s4, matrix($t0)# row = &matrix[i][0] loop2: beq $s3, $s1, end2# if (j >= 4) pause mul $t0, $s3, $s1# off = four*j add $t0, $t0, $s4# int *p = &row[j] lw $t0, ($t0)# t0 = *p add $s0, $s0, $t0# sum += t0 addi $s3, $s3, i# j++ j loop2 end2: addi $s2, $s2, 1# i++ j loop1 end1:
C struct
| ... Structs in MIPS | 97/114 |
C struct
// new type called struct _student struct _student {...};// new type called Student typedef struct _student Educatee;
Instances of structures can exist created by allocating space:
// sizeof(Student) == 56 stu1: Student stu1; .space 56 stu2: Student stu2; .space 56 stu: .space 4 Student *stu;
| ... Structs in MIPS | 98/114 |
Accessing structure components is by offset, non proper name
li $t0 5012345 sw $t0, stu1+0 # stu1.id = 5012345; li $t0, 3778 sw $t0, stu1+44 # stu1.program = 3778; la $s1, stu2 # stu = & stu2; li $t0, 3707 sw $t0, 44($s1) # stu->program = 3707; li $t0, 5034567 sw $t0, 0($s1) # stu->id = 5034567;
| ... Structs in MIPS | 99/114 |
Structs that are local to functions are allocated space on the stack
fun: int fun(int x)# prologue { addi $sp, $sp, -4 sw $fp, ($sp) movement $fp, $sp addi $sp, $sp, -4 sw $ra, ($sp) // push onto stack addi $sp, $sp, -56 Pupil st; motion $t0, $sp Student *t0 = &st;# function trunk ... compute ... // compute using t0# epilogue // to access struct addi $sp, $sp, 56 // pop st off stack lw $ra, ($sp) addi $sp, $sp, 4 lw $fp, ($sp) addi $sp, $sp, 4 jr $ra }
| ... Structs in MIPS | 100/114 |
C can laissez passer whole structures to functions, e.g.
# Pupil stu; ... # // ready values in stu struct # showStudent(stu); .information stu: .space 56 .text ... la $t0, stu addi $sp, $sp, -56# button Student object onto stack lw $t1, 0($t0)# allocate space and copy all sw $t1, 0($sp)# values in Student object lw $t1, 4($t0)# onto stack sw $t1, 4($sp) ... lw $t1, 52($t0)# and once whole object copied sw $t1, 52($sp) jal showStudent# invoke showStudent() ...
| ... Structs in MIPS | 101/114 |
Accessing struct
| ... Structs in MIPS | 102/114 |
Can likewise pass a pointer to a struct
# Student stu; # // set values in stu struct # changeWAM(&stu, float newWAM); .data stu: .infinite 56 wam: .space 4 .text ... la $a0, stu lw $a1, wam jal changeWAM ... Clearly a more efficient way to pass a large struct
Likewise, required if the function needs to update the original struct
| Compiling C to MIPS | 103/114 |
Using simplified C as an intermediate language
- makes things easier for a human to prodcue MIPS lawmaking
- does not provide an automatic way of translating
- this is provided by a compiler (east.thousand.
)dcc
- catechumen
and#include#ascertain - parse code to check syntactically valid
- manage a list of symbols used in program
- decide how to represent information structures
- allocate local variables to registers or stack
- map control structures to MIPS instructions
Maps C→C, performing various substitutions
-
File#include- replace
by contents of file#include -
name" ... uses named File.h".h -
name< ... uses File.h> in.h/usr/include
- replace
-
Name Abiding#ascertain- replace all occurences of symbol Name by Constant
- e.g
#define MAX v
→char array[MAX]char array[5]
-
Proper noun#define Params( Expression)- supercede Proper name
Params( by SubstitutedExpression) - e.g.
#define max(x,y) ((x > y) ? 10 : y)
→a = max(b,c)a = ((b > c) ? b : c)
- supercede Proper name
| ... C Pre-processor | 105/114 |
More C pre-processor substitions
Before cpp Afterward cpp x = 5; x = 5; #if 0 ten = x + 2; x = x + 1; printf("x=%d\n",x); #else x = x * 2; x = x + 2;

0 Response to "How To Assign A Char To A Register Mips"
Post a Comment