Opening Mips Code to Read in C

C: Associates Language (MIPS)


Didactics Gear up Architectures


A typical mod CPU has

  • a ready of data registers
  • a set of command registers (incl PC)
  • an arithmetic-logic unit (ALU)
  • access to random admission retentiveness (RAM)
  • a set of simple instructions
    • transfer data between memory and registers
    • push button values through the ALU to compute results
    • brand tests and transfer command of execution

Different types of processors take different configurations of the above
  • e.1000. unlike # registers, different sized registers, dissimilar instructions

Why Study Assembler? three/114

Useful to know assembly language because ...

  • sometimes you are required to use it (e.g. device handlers)
  • improves your agreement of how C programs execute
    • very helpful when debugging
    • able to avoid using known inefficient constructs
  • uber-nerdy performance tweaking (squeezing out terminal nano-s)
    • re-write that disquisitional (ofttimes-used) office in assembler

Two broad families of education fix architectures ...

RISC  (reduced didactics set computer)

  • small(ish) set of uncomplicated, full general instructions
  • split up computation & data transfer instructions
  • leading to simpler processor hardware
  • e.g. MIPS, RISC, Alpha, SPARC, PowerPC, ARM, ...
CISC  (complex instruction set up computer)
  • large(r) set of powerful instructions
  • each instruction has multiple actions (comp+store)
  • more circuitry to decode/process instructions
  • e.g. PDP, VAX, Z80, Motorola 68xxx, Intel x86, ...

... Instruction Sets 5/114

Automobile-level instructions ...

  • typically accept 1-two 32-flake words per pedagogy
  • division bits in each give-and-take into operator & operands
  • #bits for each depends on #instructions, #registers, ...
Example teaching word formats:

[Diagram:Pics/processor/instr-words-small.png]

Operands and destination are typically registers


... Instruction Sets 6/114

Common kinds of instructions (not from whatsoever real machine)

  • load Register , MemoryAddress
    • copy value stored in retention at address into named register
  • loadc Register , ConstantValue
    • re-create value into named register
  • store Register , MemoryAddress
    • re-create value stored in named annals into retentivity at address
  • jump MemoryAddress
    • transfer execution of plan to instruction at address
  • jumpif Register , MemoryAddress
    • transfer execution of program if e.m. register holds zero value

... Instruction Sets 7/114

Other common kinds of instructions (not from any real motorcar)

  • add Register1 , Registertwo , Annals3 (similarly for sub , mul , div )
    • Register3 = Registerone + Register2
  • and Register1 , Register2 , Register3 (similarly for or , xor )
    • Annalsthree = Registeri & Registertwo
  • neg Registeri , Registertwo
    • Annals2 = ~ Register1
  • shiftl Registerone , Value , Registertwo (similarly for shiftr )
    • Register2 = Registerane << Value
  • syscall Value
    • invoke a system service; which service determined by Value

... Instruction Sets eight/114

[Diagram:Pics/processor/cpu-mem-small.png]


All CPUs have plan execution logic similar:

while (1) {    instruction = memory[PC]    PC++        // motion to next instr        if (instruction == HALT)       break    else       execute(instruction) }      


PC = Program Counter, a CPU register which keeps track of execution

Note that some instructions may change PC farther (e.1000. Jump)


... Fetch-Execute Cycle ten/114

Executing an instruction involves

  • decide what the operator is
  • make up one's mind which registers, if whatsoever, are involved
  • determine which retentiveness location, if any, is involved
  • carry out the functioning with the relevant operands
  • store effect, if any, in appropriate register
Example teaching encodings (non from a real machine):

[Diagram:Pics/processor/instructions-small.png]


Instructions are simply chip patterns inside a 32-bit bit-string

Could depict car programs equally a sequence of hex digits, e.thou.

Address   Content 0x100000  0x3c041001 0x100004  0x34020004 0x100008  0x0000000c 0x10000C  0x03e00008      


Often call "assembly language" as "assembler"

Slight notational abuse, considering "assembler" also refers to a plan that translates assembly language to motorcar code


... Assembly Language 12/114

Assembler = symbolic language for writing machine code

  • write instructions using mnemonics rather than hex codes
  • reference registers using either numbers or names
  • can associate names to retentivity addresses

Mode of expression is significantly unlike to e.g. C
  • need to utilise fine-grained control of memory usage
  • required to dispense data in registers
  • control structures programmed via explicit jumps

MIPS is a well-known and relatively simple compages

  • very popular in a range of computing devices in the 1990'south
  • e.thousand. Silicon Graphics, NEC, Nintendo64, Playstation, supercomputers
We consider the MIPS32 version of the MIPS family
  • using two variants of the open-source SPIM emulator
  • qtspim ... provides a GUI front end-cease, useful for debugging
  • spim ... command-line based version, useful for testing
  • xspim ... GUI front-stop, useful for debugging, just in CSE labs
Executables and source: http://spimsimulator.sourceforge.net/

Source lawmaking for browsing under /dwelling/cs1521/spim/spim


MIPS is a machine architecture, including instruction set

SPIM is an emulator for the MIPS instruction set

  • reads text files containing instruction + directives
  • converts to machine code and loads into "memory"
  • provides debugging capabilities
    • unmarried-step, breakpoints, view registers/retentivity, ...
  • provides machinery to interact with operating system (syscall)
Likewise provides extra instructions, mapped to MIPS core set up
  • provide convenient/mnemonic means to do common operations
  • e.thousand. movement $s0,$v0   rather than addu $s0,$0,$v0

Three ways to execute MIPS lawmaking with SPIM

  • spim ... control line tool
    • load programs using -file option
    • collaborate using stdin/stdout via login final
  • qtspim ... GUI environment
    • load programs via a load button
    • collaborate via a pop-up stdin/stdout terminal
  • xspim ... GUI environs
    • similar to qtspim , but non every bit pretty
    • requires X-windows server

Command-line tool:

[Diagram:Pics/mips/use-spim-small.png]


GUI tool:

[Diagram:Pics/mips/use-qtspim-small.png]


MIPS Machine Archtecture eighteen/114

MIPS CPU has

  • 32 × 32-flake general purpose registers
  • sixteen × 64-bit double-precision registers
  • PC ... 32-bit register (always aligned on 4-byte purlieus)
  • Hullo,LO ... for storing results of multiplication and division
Registers can be referred to as $0..$31 or by symbolic names

Some registers have special uses e.k.

  • register $0 always has value 0, cannot exist written
  • registers $1 , $26 , $27 reserved for use by organisation
More details on following slides ...

... MIPS Car Archtecture 19/114

Registers and their usage

Reg Proper noun Notes
$0 naught the value 0, not changeable
$1 $at assembler temporary; used to implement pseudo-ops
$2 $v0 value from expression evaluation or role return
$3 $v1 value from expression evaluation or function render
$iv $a0 start argument to a part/subroutine, if needed
$5 $a1 2nd argument to a function/subroutine, if needed
$6 $a2 third argument to a function/subroutine, if needed
$7 $a3 4th argument to a office/subroutine, if needed
$viii .. $xv $t0 .. $t7 temporary; must be saved by caller to subroutine;
subroutine can overwrite


... MIPS Auto Archtecture twenty/114

More than register usage ...

Reg Proper noun Notes
$16 .. $23 $s0 .. $s7 southwardafe part variable;
must not exist overwritten by called subroutine
$24 .. $25 $t8 .. $t9 temporary; must be saved by caller to subroutine;
subroutine can overwrite
$26 .. $27 $k0 .. $k1 for chiliadernel use; may change unexpectedly
$28 $gp global pointer
$29 $sp stack pointer
$thirty $fp frame pointer
$31 $ra return address of about recent caller


... MIPS Machine Archtecture 21/114

Floating indicate register usage ...

Reg Notes
$f0 .. $f2 agree floating-point function results
$f4 .. $f10 temporary registers; not preserved across function calls
$f12 .. $f14 used for beginning ii double-precision function arguments
$f16 .. $f18 temporary registers; used for expression evaluation
$f20 .. $f30 saved registers; value is preserved across part calls

Notes:

  • registers come up in pairs of two × 32-bits
  • but even registers are addressed for double-precision

MIPS Assembly Linguistic communication 22/114

MIPS assembly language programs incorporate

  • comments ... introduced by #
  • labels ... appended with :
  • directives ... symbol beginning with .
  • associates language instructions
Programmers need to specify
  • data objects that alive in the information region
  • functions (pedagogy sequences) that live in the code/text region
Each educational activity or directive appears on its ain line

... MIPS Associates Linguistic communication 23/114

Case MIPS assembler plan:

        # hello.southward ... print "Hello, MIPS"        .data        # the data segment        msg:        .asciiz        "How-do-you-do, MIPS\n"        .text        # the code segment        .globl        main        main:        la $a0, msg        # load the argument string        li $v0, iv        # load the organisation call (print)        syscall        # print the string        jr $ra        # render to caller (__start)      


Color coding: label, directive, annotate


... MIPS Assembly Language 24/114

Generic structure of MIPS programs

        # Prog.south ... annotate giving description of office        # Writer ...        .data        # variable declarations follow this line        # ...        .text        # instructions follow this line                .globl master main:        # indicates start of code        # (i.e. first user instruction to execute)        # ...        # End of plan; leave a blank line to make SPIM happy      

... MIPS Assembly Linguistic communication 25/114

Some other instance MIPS assembler program:

        .data        a:        .word        42        # int a = 42;        b:        .space        four        # int b;        .text        .globl        master        main:     lw   $t0, a        # reg[t0] = a        li   $t1, eight        # reg[t1] = eight        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 retentiveness layout

Region Address Notes
text 0x00400000 contains just instructions; read-simply; cannot expand
data 0x10000000 data objects; readable/writeable; can exist expanded
stack 0x7fffefff grows down from that address; readable/writeable
k_text 0x80000000 kernel lawmaking; read-only; simply attainable kernel mode
k_data 0x90000000 kernel data; read/write; simply attainable kernel mode


MIPS has several classes of instructions:

  • load and shop .. transfer information between registers and memory
  • computational ... perform arithmetic/logical operations
  • jump and branch ... transfer control of programme execution
  • coprocessor ... standard interface to various co-processors
  • special ... miscellaneous tasks (due east.g. syscall)
And several addressing modes for each instruction
  • between memory and register (straight, indirect)
  • constant to register (firsthand)
  • register + register + destination register

... MIPS Instructions 28/114

MIPS instructions are 32-bits long, and specify ...

  • an operation (e.1000. load, store, add, co-operative, ...)
  • ane or more operands (e.m. registers, retentiveness addresses, constants)
Some possible teaching formats

[Diagram:Pics/processor/mips-instr-small.png]


Retentiveness addresses can be given by

  • symbolic name (label) (effectively, a constant)
  • indirectly via a register (effectively, pointer dereferencing)
Examples:
prog: a:    lw    $t0, var        # accost via proper noun        b:    lw    $t0, ($s0)        # indirect addressing        c:    lw    $t0, 4($s0)        # indexed addressing      

If $s0 contains 0x10000000 and &var = 0x100000008

  • computed address for a: is 0x100000008
  • computed accost for b: is 0x100000000
  • computed address for c: is 0x100000004

... Addressing Modes thirty/114

Addressing modes in MIPS

Format Address ciphering
(annals) address = *register = contents of annals
thou address = k
1000(register) address = k + *register
symbol address = &symbol = address of symbol
symbol ± g address = &symbol ± one thousand
symbol ± k(register) accost = &symbol ± (k + *register)

where k is a literal constant value (east.g. 4 or 0x10000000 )


... Addressing Modes 31/114

Examples of load/store and addressing:

                  .data vec: .space   16          # int vec[4], xvi bytes of storage          .text __start:        la  $t0, vec          # reg[t0] = &vec          li  $t1, 5          # reg[t1] = v          sw  $t1, ($t0)          # vec[0] = reg[t1]          li  $t1, 13          # reg[t1] = xiii          sw  $t1, 4($t0)          # vec[1] = reg[t1]          li  $t1, -7          # reg[t1] = -7          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 tin dispense different-sized operands

  • unmarried bytes,   two bytes ("halfword"),   4 bytes ("discussion")
Many instructions also have variants for signed and unsigned

Leads to many opcodes for a (conceptually) unmarried operation, due east.g.

  • LB ... load one byte from specified accost
  • LBU ... load unsigned byte from specified address
  • LH ... load 2 bytes from specified accost
  • LHU ... load unsigned 2-bytes from specified address
  • LW ... load four bytes (one give-and-take) from specified accost
  • LA ... load the specified address
All of the above specify a destination register

MIPS Pedagogy Prepare 33/114

The MIPS processor implements a base set of instructions, due east.thousand.

  • lw , sw , add , sub , and , or , sll , slt , beq , j , jal , ...
Augmented past a fix of pseudo-instructions, e.m.
  • move , rem , la , li , blt , ...
Each pseudo-educational activity maps to one or more base instructions, e.g.
Pseudo-didactics       Base instruction(south)        li        $t5, const          ori  $t5, $0, const        la        $t3, characterization          lui  $at, &characterization[31..16]                          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, characterization      

Notation: apply of $at register for intermediate results


... MIPS Instruction Set 34/114

In describing instructions:

Syntax Semantics
$Reg equally source, the content of the annals, reg[Reg]
$Reg as 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.one thousand. Label($Reg))
Addr as source, the content of memory jail cellmemory[Addr]
Addr equally destination, value is stored inretentiveness[Addr] = value

Finer ...

  • treat registers asunsigned int reg[32]
  • treat memory asunsigned char mem[232]

... MIPS Educational activity Fix 35/114

Examples of data movement instructions:

                  la          $t1,label          # reg[t1] = &label          lw   $t1,characterization          # reg[t1] = memory[&label]          sw   $t3,label          # memory[&characterization] = reg[t3]          # &label must be 4-byte aligned          lb   $t2,label          # reg[t2] = memory[&label]          sb   $t4,label          # retention[&label] = reg[t4]          move          $t2,$t3          # reg[t2] = reg[t3]          lui  $t2,const          # reg[t2][31:16] = const              

Examples of bit 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 Instruction Set 36/114

Examples of arithmetics instructions:

                  add  $t0,$t1,$t2          # reg[t0] = reg[t1] + reg[t2]          #   add together as signed (2's complement) ints          sub  $t2,$t3,$t4          # reg[t2] = reg[t3] + reg[t4]          addi $t2,$t3, v          # 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 as unsigned integers          mult $t3,$t4          # (Hi,Lo) = reg[t3] * reg[t4]          #   store 64-bit result in registers Hullo,Lo          div  $t5,$t6          # Lo = reg[t5] / reg[t6] (integer quotient)          # Hi = reg[t5] % reg[t6] (remainder)          mfhi $t0          # reg[t0] = reg[Hullo]          mflo $t1          # reg[t1] = reg[Lo]          # used to get result of MULT or DIV              

... MIPS Didactics Set 37/114

Examples of testing and branching instructions:

                  seq  $t7,$t1,$t2          # reg[t7] = one 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] = 1 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 = &label if (reg[t1] != reg[t2])          bgt          $t1,$t2,label          # PC = &characterization if (reg[t1] > reg[t2])          bltz $t2,characterization          # PC = &characterization if (reg[t2] < 0)          bnez $t3,label          # PC = &label if (reg[t3] != 0)              

After each branch instruction, execution continues at new PC location


... MIPS Instruction Set 38/114

Special jump instruction for invoking functions

                  jal  characterization          # make a subroutine call          # relieve PC in $ra, fix PC to &label          # use $a0,$a1 as params, $v0 as return              

[Diagram:Pics/processor/fn-call-small.png]


... MIPS Instruction Gear up 39/114

SPIM interacts with stdin/stdout via syscall s

Service Code Arguments Result
print_int 1 $a0 = integer
print_float 2 $f12 = float
print_double iii $f12 = double
print_string 4 $a0 = char *
read_int 5 integer in $v0
read_float half-dozen bladder in $f0
read_double 7 double in $f0
read_string viii $a0 = buffer, $a1 = length cord in buffer
(including "\northward\0")


... MIPS Pedagogy Set xl/114

Directives (instructions to assembler, not MIPS instructions)

                  .text          # following instructions placed in text          .data          # following objects placed in data          .globl          # brand symbol available globally          a:  .infinite 18          # uchar a[18];  or  uint a[iv];          .marshal 2          # align next object on 22-byte addr          i:  .word two          # unsigned int i = 2;          v:  .discussion 1,iii,5          # unsigned int v[3] = {1,3,v};          h:  .half 2,4,half-dozen          # unsigned short h[3] = {2,4,6};          b:  .byte 1,2,iii          # unsigned char b[iii] = {one,ii,3};          f:  .float 3.xiv          # float f = 3.14;          due south:  .asciiz "abc"          # char s[4] {'a','b','c','\0'};          t:  .ascii "abc"          # char s[3] {'a','b','c'};              

Writing direct in MIPS assembler is difficult (impossible?)

Strategy for producing likely right MIPS code

  • develop the solution in C
  • map to "simplified" C
  • interpret each simplified C statement to MIPS instructions
Simplified C
  • does not have while , switch , complex expressions
  • does have uncomplicated if , goto , one-operator expressions
  • does not accept function calls and auto local variables
  • does have jump-and-remember-where-you-came-from

... MIPS Programming 42/114

Example translating C to MIPS:

C             Simplified C   MIPS Assembler ------------  ------------   -------------- int ten = 5;    int x = 5;     ten:  .word 5 int y = 3;    int y = 3;     y:  .word 3 int z;        int z;         z:  .space iv               int t;                                       lw  $t0, 10                              lw  $t1, y z = 5*(x+y);   t = 10+y;      add $t0, $t0, $t1                              li  $t1, 5                t = 5*t;      mul $t0, $t0, $t1                z = t;        sw  $t0, z      

... MIPS Programming 43/114

Simplified C makes all-encompassing employ of

  • labels ... symbolic proper noun for C statement
  • goto ... transfer control to labelled statement
Example:
Standard C            Simplified C ------------------    ------------------ i = 0; due north = 0;         i = 0; due north = 0;  while (i < 5) {        loop:        north = n + i;           if (i >= 5)        goto        stop;    i++;                 n = n + i; }                       i++;        goto        loop;        end:      

... MIPS Programming 44/114

Beware: registers are shared past all parts of the code.

One function can overwrite value set up by another function

int x;        // first global variable        int y;        // 2d global variable        int chief(void)          int f(int n) {                       {    ten = 5;                  y = 1;    y = f(x);               for (x = 1; x <= north; 10++)    printf("...",x,y);         y = y * x;    return 0;               return y; }                       }      

Later the office, x == vi and y == 120

It is sheer coincidence that y has the right value.


... MIPS Programming 45/114

Need to be careful managing registers

  • follow the conventions implied by register names
  • preserve values that need to be saved across function calls
Within a function
  • you manage register usage every bit you like
  • typically making employ of $t? registers
When making a function phone call
  • you transfer control to a dissever piece of code
  • which may modify the value of whatever non-preserved annals
  • $s? registers must exist preserved past function
  • $a? , $5? , $t? registers may be modified by role

Rendering C in MIPS 46/114

C provides expression evaluation and assignment, eastward.1000.

  • ten = (1 + y*y) / 2;   z = 1.0 / 2; ...
MIPS provides register-register operations, e.g.
  • move Rd,Rs , li Rd,Const , add , div , and , ...
C provides a range of control structures
  • sequence ( ; ), if , while , for , pause , continue , ...
MIPS provides testing/branching instructions
  • seq , slti , sltu , ..., beq , bgtz , bgezal , ..., j , jr , jal , ...
We need to return C's structures in terms of testing/branching

Sequence is easy S1 ; Southward2 mips(South1) mips(Southward2)


... Rendering C in MIPS 47/114

Simple example of consignment and sequence:

int x;        x: .infinite 4 int y;        y: .space 4  x = 2;           li   $t0, 2                  sw   $t0, ten  y = x;           lw   $t0, x                  sw   $t0, y  y = x+3;         lw   $t0, x                  addi $t0, 3                  sw   $t0, y      

Arithmetic Expressions 48/114

Expression evaluation involves

  • describing the process as a sequence of binary operations
  • managing data menses between the operations
Instance:
# x = (1 + y*y) / 2    lw   $t0, y             mul  $t0, $t0, $t0      addi $t0, $t0, ane        li   $t1, ii             div  $t0, $t1           mflo $t0                sw   $t0, x                

Information technology 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)    {        Statementsi                }          if (t0 == 0) else                           goto else_part;    {        Statementstwo                }        Statementsi                goto end_if;        else_part:        Statements2                end_if:      

... Conditional Statements 50/114

Conditional statements (e.g. if )

        if_stat:        if (Cond)                  t0 = evaluate (Cond)    {        Statementsane                }        beqz        $t0,        else_part        else                       execute        Statements1                {        Statementsii                }        j        end_if        else_part:        execute        Statements2                end_if:      

... Conditional Statements 51/114

Example of if-then-else:

                  int x;           10 is $t0 int y;           y is $t1 char z;          z is $a0  x = getInt();    li   $v0, 5                  syscall                  move $t0, $v0  y = getInt();    li   $v0, five                  syscall                  move $t1, $v0  if (ten == y)      bne  $t0, $t1, printN    z = 'Y';    setY:                  li   $a0, 'Y'                  j    print else           setN:    z = 'Northward';      li   $a0, 'N'                  j    print          # redundant          print: putChar(z);      li   $v0, 11                  syscall              

... Provisional Statements 52/114

Could make switch by outset converting to if

switch (Expr) {              tmp = Expr; example Val1:                   if (tmp == Vali)    Statements1        ; break;         { Statements1; } instance Val2:                   else if (tmp == Valii        example Val3:                            || tmp == Val3        case Val4:                            || tmp == Val4)    Statements2        ; break;         { Statementstwo; } case Valfive:                   else if (tmp == Valfive)    Statements3        ; break;         { Statements3; } default:                     else    Statements4        ; break;         { Statements4; } }      

... Conditional Statements 53/114

Bound table: an alternative implementation of switch

  • works all-time for pocket-size, dense range of case values (e.g. 1..ten)
                  jump_tab:                                 .word c1, c2, c2, c2, c3                              switch:                                  t0 = evaluate Expr switch (Expr) {                  if (t0 < 1 || t0 > 5) case one:                             spring to default    Statementsone          ; break;          dest = jump_tab[(t0-1)*4] case 2:                          bound to dest case 3:                      c1: execute Statements1          case 4:                          spring to end_switch    Statements2          ; break;      c2: execute Statements2          case 5:                          jump to end_switch    Statements3          ; break;      c3: execute Statements3          default:                         jump to end_switch    Statements4          ; break;      default: }                                execute Statementsfour          end_switch:              

Boolean Expressions 54/114

Boolean expressions in C are curt excursion

(Cond1        && Cond2        && ... && Condn)      

Evaluates by

  • evaluate Condane ; if 0 then return 0 for whole expression
  • evaluate Cond2 ; if 0 and then render 0 for whole expression
  • ...
  • evaluate Condn ; if 0 then render 0 for whole expression
  • otherwise, return 1
In C, whatever not-cypher value is treated as truthful; MIPS tends to use 1 for true

C99 standard defines return value for booleans expressions as 0 or 1


... Boolean Expressions 55/114

Similarly for disjunctions

(Cond1        || Cond2        || ... || Conddue north)      

Evaluates past

  • evaluate Condane ; if !0 and so return 1 for whole expression
  • evaluate Cond2 ; if !0 and so return ane for whole expression
  • ...
  • evaluate Condn ; if !0 then return one for whole expression
  • otherwise, render ane
In C, any non-zero value is treated equally true; MIPS tends to use ane for true

C99 standard defines render value for booleans expressions as 0 or 1


Iteration Statements 56/114

Iteration (e.one thousand. while )

        top_while:        while (Cond) {           t0 = evaluate Cond    Statements;        beqz        $t0,end_while        }                        execute Statements        j        top_while        end_while:      

Treat for as a special case of while

        i = 0 for (i = 0; i < Due north; i++) {       while (i < N) {     Statements;                    Statements; }                                  i++;                                 }      

... Iteration Statements 57/114

Example of iteration over an array:

                  int sum, i;               sum: .word 4        int a[5] = {1,3,v,vii,9};   a:   .word 1,3,5,7,9 ...                            ... sum = 0;                       li   $t0, 0                                   li   $t1, 0                                   li   $t2, 4    for (i = 0; i < Northward; 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, i                                   j    for                       end_for: sw   $t1, sum                                move $a0, $t1                                 li   $v0, ane                                syscall                     

When we telephone call a function:

  • the arguments are evaluated and ready up for function
  • command is transferred to the code for the function
  • local variables are created
  • the function lawmaking is executed in this environment
  • the return value is set up
  • command transfers back to where the role was called from
  • the caller receives the return value

Data associated with part calls is placed on the MIPS stack.

[Diagram:Pics/processor/mips-memory-small.png]


Each function allocates a small-scale section of the stack (a frame)

  • used for: saved registers, local variables, parameters to callees
  • created in the role prologue (pushed)
  • removed in the function epilogue (popped)

Why we use a stack:
  • part f() calls g() which calls h()
  • h() runs, then finishes and returns to g()
  • g() continues, then finishes and returns to f()
i.e. last-chosen, exits-first (last-in, first-out) behaviour

How stack changes equally functions are called and render:

[Diagram:Pics/processor/mips-fn-calls-small.png]


Register usage conventions when f() calls g() :

  • caller saved registers (saved past f() )
    • f() tells thou() "If at that place is anything I desire to preserve in these registers, I take already saved it before calling you"
    • g() tells f() "Don't assume that these registers will be unchanged when I render to you"
    • east.g. $t0 .. $t9 , $a0 .. $a3 , $ra
  • callee saved registers (saved by k() )
    • f() tells k() "I assume the values of these registers will be unchanged when you return"
    • thou() tells f() "If I demand to apply these registers, I will salve them offset and restore them before returning"
    • eastward.m. $s0 .. $s7 , $sp , $fp

Contents of a typical stack frame:

[Diagram:Pics/processor/mips-stack-frame-small.png]


Aside: MIPS Branch Delay Slots 64/114

The real MIPS compages is "pipelined" to ameliorate efficiency

  • one pedagogy can first before the previous one finishes
For branching instructions (e.g. jal ) ...
  • instruction following branch is executed earlier branch completes
To avert potential bug use nop immediately later branch

A trouble scenario, and its solution (branch filibuster slot):

# Implementation of        print(compute(42))        li   $a0, 42           li   $a0, 42 jal  compute           jal  compute move $a0, $v0          nop jal  print             move $a0,$v0                        jal  print      

Since SPIM is not pipelined, the nop is not required


Bated: Why practise we demand both $fp and $sp? 65/114

During execution of a part

  • $sp tin alter (e.one thousand. pushing params, adding local vars)
  • may need to reference local vars on the stack
  • useful if they can be defined by an get-go relative to fixed point
  • $fp provides a fixed bespeak during function lawmaking execution

                  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; }              

Function Calling Protocol 66/114

Earlier one role calls another, it needs to

  • identify 64-bit double args in $f12 and $f14
  • identify 32-bit arguments in the $a0 .. $a3
  • if more than iv args, or args larger than 32-bits ...
    • button value of all such args onto stack
  • salvage whatsoever non- $due south? registers that need to be preserved
    • push value of all such registers onto stack
  • jal address of function (normally given by a label)
Pushing value of e.one thousand. $t0 onto stack means:
addi $sp, $sp, -4 sw   $t0, ($sp)      

... Function Calling Protocol 67/114

Example: uncomplicated function call

int main() {        // 10 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; }      

... Office Calling Protocol 68/114

Simple function phone call:

[Diagram:Pics/processor/mips-fn-args0-small.png]


... Role Calling Protocol 69/114

Execution of sum() role:

[Diagram:Pics/processor/mips-fn-body0-small.png]


... Function Calling Protocol lxx/114

Example: function f() calls function g(a,b,c,d,due east,f)

int f(...) {            int a,b,c,d,eastward,f;    ...    a = thou(a,b,c,d,e,f);    ... } int thou(int u,five,w,10,y,z) {    render u+five+w*due west*x*y*z; }      

... Function Calling Protocol 71/114

Function call in MIPS:

[Diagram:Pics/processor/mips-fn-args-small.png]


... Function Calling Protocol 72/114

Execution of g() function:

[Diagram:Pics/processor/mips-fn-body-small.png]


Structure of Functions 73/114

Functions in MIPS have the following general structure:

                  # start of part          FuncName:          #          function prologue          #   gear up up stack frame ($fp, $sp)    #   save relevant registers (incl. $ra)    ...    #          part trunk          #   perform computation using $a0, etc.    #   leaving consequence in          $v0          ...    #          role epilogue          #   restore saved registers (esp. $ra)    #   clean up stack frame ($fp, $sp)          jr  $ra              

Aim of prologue: create environs for function to execute in.


Before a function starts working, it needs to ...

  • create a stack frame for itself  (change $fp and $sp )
  • save the return address ( $ra ) in the stack frame
  • save whatsoever $southward? registers that information technology plans to modify
We tin can make up one's mind the initial size of the stack frame via
  • four bytes for saved $fp + 4 bytes for saved $ra
  • + four bytes for each saved $s?
Changing $fp and $sp ...
  • new $fp = onetime $sp - iv
  • new $sp = sometime $sp - size of frame (in bytes)

... Function Prologue 75/114

Example of part fx() , which uses $s0 , $s1 , $s2

[Diagram:Pics/processor/mips-fn-prologue-small.png]


... Role Prologue 76/114

Alternatively ... (more than explicit push button )

[Diagram:Pics/processor/mips-fn-prologue2-small.png]


... Function Prologue 77/114

Alternatively ... (relative to new $fp )

[Diagram:Pics/processor/mips-fn-prologue3-small.png]


Before a function returns, it needs to ...

  • identify the return value in $v0 (and maybe $v1 )
  • pop whatever pushed arguments off the stack
  • restore the values of whatever saved $south? registers
  • restore the saved value of $ra (render accost)
  • remove its stack frame  (change $fp and $sp )
  • render to the calling part   ( jr $ra )
Locations of saved values computed relative to $fp

Changing $fp and $sp ...

  • new $sp = onetime $fp + 4
  • new $fp = retentiveness[ onetime $fp]

... Function Epilogue 79/114

Example of function fx() , which uses $s0 , $s1 , $s2

[Diagram:Pics/processor/mips-fn-epilogue-small.png]


Information Structures and MIPS 80/114

C information structures and their MIPS representations:

  • char ... every bit byte in retention, or low-lodge byte in register
  • int ... as word in retention, or whole register
  • double ... as 2-words in retentivity, or $f? register
  • arrays ... sequence of memory bytes/words, accessed by index
  • structs ... clamper of memory, accessed by fields/offsets
  • linked structures ... struct containing address of another struct
A char , int or double
  • could exist implemented in annals if used in pocket-size scope
  • could be implemented on stack if local to office
  • could be implemented in .data if need longer persistence

Static vs Dynamic Allocation 81/114

Static allocation:

  • uninitialised retentiveness allocated at compile/assemble-time, east.g.
    int  val;              val: .space 4 char str[20];          str: .space 20 int  vec[20];          vec: .space 80          
  • initialised memory allocated at compile/gather-fourth dimension, e.g.
    int val = v;                 val: .give-and-take 5 int arr[four] = {9,8,7,6};      arr: .give-and-take 9, 8, 7, six char *msg = "Hello\n";       msg: .asciiz "Hello\n"          

... Static vs Dynamic Allocation 82/114

Dynamic allocation (i):

  • variables local to a function
Prefer to put local vars in registers, merely if cannot ...
  • use space allocated on stack during role prologue
  • referenced during function relative to $fp
  • infinite reclaimed from stack in function epilogue
Example:
int fx(int a[]) {        int i, j, max;        i = 1; j = 2; max = i+j;    ... }      

... Static vs Dynamic Allocation 83/114

Case of local variables on the stack:

[Diagram:Pics/processor/local-vars-small.png]


... Static vs Dynamic Allotment 84/114

Dynamic allocation (ii):

  • uninitialised block of memory allocated at run-fourth dimension
    int  *ptr = malloc(sizeof(int)); char *str = malloc(20*sizeof(char)); int  *vec = malloc(twenty*sizeof(int));  *ptr = 5; strcpy(str, "a string"); vec[0] = ane;            // or  *vec = 1;            vec[one] = six;          
  • initialised block of memory allocated at run-time
    int *vec = calloc(20, sizeof(int));            // vec[i] == 0, for i in 0..xix          

... Static vs Dynamic Allocation 85/114

SPIM doesn't provide malloc() / free() functions

  • merely provides syscall 9 to extend .data
  • before syscall , prepare $a0 to the number of bytes requested
  • afterwards syscall , $v0 holds start accost of allocated chunk
Case:
li   $a0, 20        # $v0 = malloc(20)        li   $v0, 9 syscall movement $s0, $v0        # $s0 = $v0      

Cannot access allocated information by name; demand to retain address.

No way to free allocated data, and no way to align data accordingly


... Static vs Dynamic Allocation 86/114

Implementing C-similar malloc() and complimentary() in MIPS requires

  • a complete implementation of C's heap direction, i.due east.
  • a large region of retention to manage ( syscall 9)
  • ability to marker chunks of this region equally "in utilise" (with size)
  • ability to maintain list of gratis chunks
  • ability to merge free chunks to prevent fragmentation

[Diagram:Pics/processor/heap-small.png]


Can be named/initialised equally noted higher up:

vec:  .space 40        # could be either int vec[10] or char vec[xl]        nums: .word 1, iii, five, 7, 9        # int nums[6] = {1,three,5,7,9}      

Can access elements via index or cursor (arrow)

  • either arroyo needs to business relationship for size of elements
Arrays passed to functions via arrow to get-go element
  • must also pass assortment size, since not available elsewhere
Come across sumOf() exercise for an instance of passing an array to a office

... one-d Arrays in MIPS 88/114

Scanning beyond an array of N elements using index

        # 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 >= 10) pause        mul  $t0, $s0, $s2        # index -> byte get-go        lw   $a0, vec($t0)        # a0 = vec[i]        jal  impress        # impress a0        addi $s0, $s0, one        # i++        j    loop end_loop:      

Assumes the existence of a print() part to exercise printf("%d\due north",x)


... 1-d Arrays in MIPS 89/114

Scanning across an array of N elements using cursor

        # int vec[10] = {...}; # int *cur, *end = &vec[x]; # for (cur = vec; cur < cease; cur++) #    printf("%d\n", *cur);        la   $s0, vec        # cur = &vec[0]        la   $s1, vec+twoscore        # end = &vec[10]        loop:    bge  $s0, $s1, end_loop        # if (cur >= end) break        lw   $a0, ($s0)        # a0 = *cur        jal  print        # print a0        addi $s0, $s0, 4        # cur++        j    loop end_loop:      

Assumes the existence of a print() office to do printf("%d\northward",10)


... one-d Arrays in MIPS 90/114

Arrays that are local to functions are allocated space on the stack

                  fun:                         int fun(int x)          # prologue          {    addi $sp, $sp, -4    sw   $fp, ($sp)    motility $fp, $sp    addi $sp, $sp, -4    sw   $ra, ($sp)              // push a[] onto stack    addi $sp, $sp, -40           int a[10];    move $s0, $sp                int *s0 = a;          # function body          ... compute ...              // compute using s0          # epilogue          // to access a[]    addi $sp, $sp, forty            // pop a[] off stack    lw   $ra, ($sp)    addi $sp, $sp, 4    lw   $fp, ($sp)    addi $sp, $sp, 4    jr   $ra                  }              

2-d arrays could exist represented two ways:

[Diagram:Pics/processor/2d-array-small.png]


... two-d Arrays in MIPS 92/114

Representations of int matrix[4][four] ...

        # for strategy (a)        matrix: .space 64        # for strategy (b)        row0:   .space 16 row1:   .infinite xvi row2:   .space 16 row3:   .infinite 16 matrix: .discussion row0, row1, row2, row3      

At present 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];      

... 2-d Arrays in MIPS 93/114

Accessing elements:

[Diagram:Pics/processor/2d-array-access-small.png]


... 2-d Arrays in MIPS 94/114

Computing sum of all elements for strategy (a) int matrix[iv][4]

                  li  $s0, 0          # sum = 0          li  $s1, 4          # s1 = iv (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 = 4*4*i + 4*j          mul  $t1, $s3, $s1          #  matrix[i][j] is          add together  $t0, $t0, $t1          #  done as *(matrix+off)          lw   $t0, matrix($t0)          # t0 = matrix[i][j]          add  $s0, $s0, $t0          # sum += t0          addi $s3, $s3, 1          # j++          j    loop2 end2:    addi $s2, $s2, 1          # i++          j    loop1 end1:              

... ii-d Arrays in MIPS 95/114

Computing sum of all elements for strategy (b) int matrix[4][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 >= four) interruption          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 >= four) break          mul  $t0, $s3, $s1          # off = 4*j          add together  $t0, $t0, $s4          # int *p = &row[j]          lw   $t0, ($t0)          # t0 = *p          add  $s0, $s0, $t0          # sum += t0          addi $s3, $s3, ane          # j++          j    loop2 end2:    addi $s2, $s2, 1          # i++          j    loop1 end1:              

C struct s hold a collection of values accessed past proper noun

[Diagram:Pics/processor/struct-small.png]


... Structs in MIPS 97/114

C struct definitions effectively define a new type.

        // new type called struct _student        struct _student {...};        // new type chosen Student        typedef struct _student Educatee;      

Instances of structures can be created by allocating space:

        // sizeof(Educatee) == 56        stu1:             Student stu1;    .infinite 56 stu2:             Student stu2;    .infinite 56 stu:    .infinite 4       Student *stu;      

... Structs in MIPS 98/114

Accessing structure components is by offset, not proper name

li  $t0  5012345 sw  $t0,        stu1+0        # stu1.id = 5012345; li  $t0, 3778 sw  $t0,        stu1+44        # stu1.programme = 3778; la  $s1, stu2         # stu = & stu2; li  $t0, 3707 sw  $t0,        44($s1)        # stu->programme = 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 ten)          # prologue          {    addi $sp, $sp, -iv    sw   $fp, ($sp)    move $fp, $sp    addi $sp, $sp, -4    sw   $ra, ($sp)              // button onto stack          addi $sp, $sp, -56          Student st;          move $t0, $sp          Student *t0 = &st;          # function body          ... compute ...              // compute using t0          # epilogue          // to admission 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 pass whole structures to functions, eastward.g.

                  # Student stu; ... # // set values in stu struct # showStudent(stu);          .data stu: .space 56    .text    ...    la   $t0, stu    addi $sp, $sp, -56          # push Pupil object onto stack          lw   $t1, 0($t0)          # allocate space and copy all          sw   $t1, 0($sp)          # values in Educatee object          lw   $t1, 4($t0)          # onto stack          sw   $t1, four($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 within function ...

[Diagram:Pics/processor/pass-struct-by-value-small.png]


... Structs in MIPS 102/114

Tin can also laissez passer a pointer to a struct

                  # Student stu; # // prepare values in stu struct # changeWAM(&stu, float newWAM);          .data stu: .space 56 wam: .infinite 4    .text    ...    la   $a0, stu    lw   $a1, wam    jal  changeWAM    ...              

Conspicuously a more efficient way to laissez passer a big struct

Likewise, required if the part 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 non provide an automatic style of translating
  • this is provided by a compiler (e.g. dcc )
What does the compiler demand to do to convert C to MIPS?
  • convert #include and #define
  • parse lawmaking to bank check syntactically valid
  • manage a list of symbols used in plan
  • determine how to stand for information structures
  • allocate local variables to registers or stack
  • map control structures to MIPS instructions

Maps C→C, performing diverse substitutions

  • #include File
    • replace #include by contents of file
    • " name .h" ... uses named File .h
    • < name .h> ... uses File .h in /usr/include
  • #define Name Abiding
    • replace all occurences of symbol Name by Constant
    • e.thousand #define MAX 5
      char array[MAX] char array[v]
  • #define Name ( Params ) Expression
    • replace Name ( Params ) by SubstitutedExpression
    • e.m. #define max(x,y) ((ten > y) ? x : y)
      a = max(b,c) a = ((b > c) ? b : c)

... C Pre-processor 105/114

More C pre-processor substitions

                  Before cpp                          After cpp                ten = v;                    x = 5;        #if 0        x = x + 2; x = 10 + 1;                printf("ten=%d\n",ten);        #else        ten = x * 2; 10 = x + 2;        

0 Response to "Opening Mips Code to Read in C"

Postar um comentário

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel