MIPS Assembly Language
CICS 515: Part 1 Summer 2003
C vs. Assembly Lang., vs. Machine Lang. •
C, C++, Java: high-level language – easy to read, debug, write
•
Assembly: one-to-one correspondence between assembly language instructions and machine language instructions
•
High-level language program (in C)
swap(int v[], int k) {int temp; temp = v[k]; v[k] = v[k+1]; v[k+1] = temp; }
Assembly language program (for MIPS)
swap: muli $2, $5,4 add $2, $4,$2 lw $15, 0($2) lw $16, 4($2) sw $16, 0($2) sw $15, 4($2) jr $31
C compiler
Machine Language: instructions stored in memory, encoded
Assembler
Binary machine language program (for MIPS)
00000000101000010000000000011000 00000000100011100001100000100001 10001100011000100000000000000000 10001100111100100000000000000100 10101100111100100000000000000000 10101100011000100000000000000100 00000011111000000000000000001000
Assembly and Machine Instructions: • • •
•
Language of the Machine More primitive than higher level languages e.g., no sophisticated control flow Very restrictive e.g., MIPS Arithmetic Instructions
We’ll be working with the MIPS instruction set architecture – similar to other architectures developed since the 1980's – used by NEC, Nintendo, Silicon Graphics, Sony
MIPS arithmetic • •
All instructions have 3 operands Operand order is fixed (destination first) Example: C code:
A = B + C
MIPS code:
add $s0, $s1, $s2 (associated with variables by compiler)
MIPS arithmetic • •
• • •
Design Principle: simplicity favors regularity. Of course this complicates some things... C code:
A = B + C + D; E = F - A;
MIPS code:
add $t0, $s1, $s2 add $s0, $t0, $s3 sub $s4, $s5, $s0
Operands must be registers, only 32 registers provided (compared to 3 registers in Lab 2/3) Each Register is 32 bits (compared to 8 bits in Lab 2/3) Design Principle: smaller is faster. Why?
Register Names for MIPS Name Register number $zero 0 $v0-$v1 2-3 $a0-$a3 4-7 $t0-$t7 8-15 $s0-$s7 16-23 $t8-$t9 24-25 $gp 28 $sp 29 $fp 30 $ra 31
Usage the constant value 0 values for results and expression evaluation arguments temporaries saved more temporaries global pointer stack pointer frame pointer return address
Registers vs. Memory • • •
Arithmetic instructions operands must be registers, — only 32 registers provided Compiler associates variables with registers What about programs with lots of variables
Input
Control Memory Datapath Processor
Output I/O
Memory Organization • • •
Viewed as a large, single-dimension array, with an address. A memory address is an index into the array "Byte addressing" means that the index points to a byte of memory.
0 1
8 bits of data
2 3 4 5 6
8 bits of data
8 bits of data
8 bits of data 8 bits of data 8 bits of data 8 bits of data
...
Memory and Registers • •
Registers are each 32 bits, while memory locations hold 8 bits each So when we write a register to memory, we actually fill four memory locations ...
32 bits of data
19 20 21
8 bits of data
22 23 24 25
8 bits of data
8 bits of data 8 bits of data
8 bits of data 8 bits of data 8 bits of data
... •
When we read a register from memory, we read 4 memory locations
Load and Store Instructions •
To transfer a word from memory to a register: “load” – Suppose register $s3 contains address in memory in which desired word is located – Suppose we want to put the word into register $t0 – Then, we can use the following instruction:
lw
$t0, 0($s3)
Example: Suppose register $s3 contains 00000020 Then, executing the above instruction will go to location 20 in memory, read a word (32 bits), and store the word in register $t0
Load and Store Instructions
•
To transfer a word from a register to memory: “store”
sw
$t0,
0($s3)
– This instruction writes the value in register $t0 into memory – The target address in memory is the address stored in register $s0 Example: Suppose register $s3 contains 00000020 and suppose register $t0 contains 00000054 (base 16). Then, when the above instruction is executed, the value 00000054 is stored in memory locations 20, 21, 22, and 23. Since each memory location holds 8 bits, it takes 4 locations to store the 32 bit word.
Load and Store Instructions •
Can specify an “offset”:
sw
$t0,
32($s3)
– If S3 contains 20, this instruction writes word to memory starting at locations 52 (32+20). •
Can use this to access arrays: – In the above example, $s3 would contain the base of the array To write to element 0 of array: sw $t0, 0($s3) To write to element 1 of array: sw $t0, 4($s3) (note this assumes each array element is 4 bytes long) To write to element 2 of array: sw $t0, 8($s3)
Instructions • •
•
Load and store instructions Example: C code:
A[8] = h + A[8];
MIPS code:
lw $t0, 32($s3) add $t0, $s2, $t0 sw $t0, 32($s3)
Remember arithmetic operands are registers, not memory!
Our First Example •
Can we figure out the code? swap(int v[], int k); { int temp; temp = v[k] v[k] = v[k+1]; v[k+1] = temp; swap: } muli $t0, $a1, 4 add $t0, $a0, $t0 lw $t1, 0($t0) lw $t2, 4($t0) sw $t2, 0($t0) sw $t1, 4($t0)
So far we’ve learned: •
MIPS — loading words but addressing bytes — arithmetic on registers only
•
Instruction
Meaning
add $s1, $s2, $s3 sub $s1, $s2, $s3 lw $s1, 100($s2) sw $s1, 100($s2)
$s1 = $s2 + $s3 $s1 = $s2 – $s3 $s1 = Memory[$s2+100] Memory[$s2+100] = $s1
Machine Language •
Instructions, like registers and words of data, are also 32 bits long – Example: add $t0, $s1, $s2 – registers have numbers, $t0=9, $s1=17, $s2=18
•
Instruction Format: 000000 10001 op
10010
rs
rt
01000 rd
00000
100000
shamt
funct
Machine Language •
Consider the load-word and store-word instructions, – Introduce a new type of instruction format – I-type for data transfer instructions – other format was R-type for register
•
Example: lw $t0, 32($s2) 35
18
9
op
rs
rt
32 16 bit number
Stored Program Concept • •
Instructions are bits Programs are stored in memory — to be read or written just like data
Processor
•
Memory
memory for data, programs, compilers, editors, etc.
Fetch & Execute Cycle – Instructions are fetched and put into a special register – Bits in the register "control" the subsequent actions – Fetch the “next” instruction and continue
Control •
Decision making instructions – alter the control flow, – i.e., change the "next" instruction to be executed
•
MIPS conditional branch instructions: bne $t0, $t1, Label beq $t0, $t1, Label
•
Example:
if (i==j) { h = i + j; }
bne $s0, $s1, Label add $s3, $s0, $s1 Label: ....
Control •
MIPS unconditional branch instructions: j label
•
Example: if (i!=j) h=i+j; else h=i-j;
•
beq $s4, $s5, Lab1 add $s3, $s4, $s5 j Lab2 Lab1: sub $s3, $s4, $s5 Lab2: ...
Take Home Exercise: Build a simple for-loop
Addresses in Branches and Jumps •
•
•
Instructions: bne $t4,$t5,Label beq $t4,$t5,Label j Label
Next instruction is at Label if $t4 ° $t5 Next instruction is at Label if $t4 = $t5 Next instruction is at Label
Formats: I
op
J
op
rs
rt
16 bit address
26 bit address
But an address is 32 bits! — How do we handle this?
Addresses in Branches and Jumps
•
Formats: I
op
J
op
rs
rt
16 bit address
26 bit address
•
Jump instructions just use high order bits of PC – address boundaries of 256 MB
•
For branches, encode offset from current PC rather than the absolute value of the target address
So far: •
•
Instruction
Meaning
add $s1,$s2,$s3 sub $s1,$s2,$s3 lw $s1,100($s2) sw $s1,100($s2) bne $s4,$s5,L beq $s4,$s5,L j Label
$s1 = $s2 + $s3 $s1 = $s2 – $s3 $s1 = Memory[$s2+100] Memory[$s2+100] = $s1 Next instr. is at Label if $s4 ° $s5 Next instr. is at Label if $s4 = $s5 Next instr. is at Label
Formats: R
op
rs
rt
rd
I
op
rs
rt
16 bit address
J
op
shamt
funct
26 bit address
Control Flow • •
We have: beq, bne, what about Branch-if-less-than? New instruction: if $s1 < $s2 then $t0 = 1 slt $t0, $s1, $s2 else $t0 = 0
•
Can use this instruction to build "blt $s1, $s2, Label" — can now build general control structures
2
Constants •
Small constants are used quite frequently (50% of operands) e.g., A = A + 5; B = B + 1; C = C - 18;
•
MIPS Instructions: addi $29, $29, 4 slti $8, $18, 10 andi $29, $29, 6 ori $29, $29, 4
3
How about larger constants? • •
We'd like to be able to load a 32 bit constant into a register Must use two instructions, new "load upper immediate" instruction lui $t0, 1010101010101010 1010101010101010
•
filled with zeros
0000000000000000
Then must get the lower order bits right, i.e., ori $t0, $t0, 1010101010101010
ori
1010101010101010
0000000000000000
0000000000000000
1010101010101010
1010101010101010
1010101010101010
Assembly Language vs. Machine Language •
• •
•
Assembly provides convenient symbolic representation – much easier than writing down numbers – e.g., destination first Machine language is the underlying reality – e.g., destination is no longer first Assembly can provide 'pseudoinstructions' – e.g., “move $t0, $t1” exists only in Assembly – would be implemented using “add $t0,$t1,$zero” When considering performance you should count real instructions
To summarize:
add
MIPS assembly language Example Meaning add $s1, $s2, $s3 $s1 = $s2 + $s3
Three operands; data in registers
subtract
sub $s1, $s2, $s3
$s1 = $s2 - $s3
Three operands; data in registers
addi $s1, $s2, 100 lw $s1, 100($s2) sw $s1, 100($s2) lb $s1, 100($s2) sb $s1, 100($s2) lui $s1, 100
$s1 = $s2 + 100 Used to add constants $s1 = Memory[$s2 + 100 Word from memory to register Memory[$s2 + 100] = $s1 Word from register to memory $s1 = Memory[$s2 + 100 Byte from memory to register Memory[$s2 + 100] = $s1 Byte from register to memory Loads constant in upper 16 bits $s1 = 100 * 216
beq
$s1, $s2, 25
if ($s1 == $s2 ) go to PC + 4 + 100
Equal test; PC-relative branch
branch on not equal bne
$s1, $s2, 25
if ($s1 != $s2 ) go to PC + 4 + 100
Not equal test; PC-relative
$s1, $s2, $s3
if ($s2 < $s3 ) $s1 = 1; else $s1 = 0
Compare less than; for beq, bne
Category
Arithmetic
Instruction
add immediate load w ord store w ord Data transfer load byte store byte load upper immediate branch on equal
Conditional branch
Unconditional jump
set on less than
slt
set less than immediate
slti
jump jump register jump and link
j jr jal
$s1, $s2, 100 if ($s2 < 100 ) $s1 = 1;
Comments
Compare less than constant
else $s1 = 0
2500 $ra 2500
go to 10000 Jump to target address $ra go to For sw itch, procedure return $ra = PC + 4; go to 2500 For procedure call