introduction to isas and assembly language
DESCRIPTION
Introduction to ISAs and Assembly Language. Instruction Set Architecture Classification. According to the type of internal storage in a processor the basic types are Stack Accumulator General Purpose register Register – Memory Register – Register/ Load – Store Memory – Memory (obsolete) - PowerPoint PPT PresentationTRANSCRIPT
Instruction Set Architecture Classification
According to the type of internal storage in a processor the basic types are
• Stack
• Accumulator
• General Purpose register
• Register – Memory
• Register – Register/ Load – Store
• Memory – Memory (obsolete)
• Extended accumulator/extended general purpose register
Stack
• A Top-of-Stack (TOS) register points to the top input operand, which is combined with the operand below
• The first operand is removed from the stack, and the result is stored in the place of the second operand, while TOS is updated
ALU
...
...
...
TOS
Processor
Memory
Accumulator
One operand implicitly in accumulator, the other in memory and result in accumulator
ALU
...
...
Register - Memory
ALU
...
...
...
...
One operand is in a register the other in memory and the result is stored in a register
Register – Register/ Load – Store
ALU
...
...
...
...
Both operands and result are stored in registers
Addressing Modes• Register
• ADD R4, R3 ; Regs[R4] ←Regs[R4] + Regs[R3]• Immediate
• ADD R4, #3 ; Regs[R4] ←Regs[R4] + 3• Displacement
• ADD R4, 100(R1) ; Regs[R4] ←Regs[R4] + Mem[100+Regs[R1]]• Register Indirect
• ADD R4, (R1) ; Regs[R4] ←Regs[R4] + Mem[Regs[R1]]• Indexed
• ADD R3, (R1+R2) ; Regs[R3] ←Regs[R3] + Mem[Regs[R1]+ Regs[R2]]• Direct or absolute
• ADD R1, (1001) ; Regs[R1] ←Regs[R1] + Mem[1001]• Memory indirect
• ADD R1, @(R3) ; Regs[R1] ←Regs[R1] + Mem[Mem[Regs[R3]]]• Autoincrement
• ADD R1, (R2)+ ; Regs[R1] ←Regs[R1] + Mem[Regs[R2]] Regs[R2] ← Regs[R2] + d
• Autodecrement• ADD R1, -(R2) ; Regs[R2] ← Regs[R2] - d
Regs[R1] ←Regs[R1] + Mem[Regs[R2]]
• Scaled• ADD R1, 100(R2)[R3] ; Regs[R1] ←Regs[R1] + Mem[100 + Regs[R2] + Regs[R3]*d]
Instruction encoding
• Variable length (x86)
• Fixed length (ARM, MIPS, PowerPC)
• Hybrid (MIPS16, Thumb, TI TMS320C54x)
Taking orders• A computer does what you tell it to do
• Not necessarily what you want it to do...
3.1
• We give computers orders by means of instructions
• Instructions tell the computer what it should be doing, right now
• Arithmetic• Logic• Data movement• Control
Binary review
Binary representations of numbers consist of only 1’s and 0’sBinary representations of numbers consist of only 1’s and 0’s
01012 = 510
10002 = 810
11111112 = 12710
Unsigned (always positive)binary numbersUnsigned (always positive)binary numbers 210 = 1024 = 1K 1,000
220 = 1,048,576 = 1M 1,000,000 230 = 1,073,741,824 = 1G 1,000,000,000
210 = 1024 = 1K 1,000 220 = 1,048,576 = 1M 1,000,000 230 = 1,073,741,824 = 1G 1,000,000,000
Binary Facts:Binary Facts:
Converting between binary and hexBinary0000000100100011010001010110011110001001101010111100110111101111
Group bits together in groups of 4Group bits together in groups of 4
Assign the appropriate hex digit to each groupAssign the appropriate hex digit to each group
DoneDone
10001100101100100001112
--> 10 0011 0010 1100 1000 01112
10 0011 0010 1100 1000 01112
--> 2 3 2 C 8 7
= 232C8716
Hexadecimal0123456789ABCDEF
The Translation Process
Computers speak in binary. We don’t.
A = B + C
add $1, $2, $3
000000 00010 00011 00001 00000 100000
Compiler
Assembler
High-level languageHigh-level language
Assembly languageAssembly language
Machine languageMachine language
Compilers and Assemblerstranslate from one languageto another.
3.2
MIPS Instructions
add A, B, C
OperationOperation DestinationDestination SourcesSources
A = B + CA = B + C
sub D, A, B
D = A - BD = A - B
In MIPS,All register-to-registerarithmetic instructionshave three operands.
In MIPS,All register-to-registerarithmetic instructionshave three operands.
3.2
Operands
add A, B, C
What are A, B, and C?
The operands of arithmetic instructions are always registersThe operands of arithmetic instructions are always registers
add $17, $18, $19
Add contents of registers 18 and 19 and put result in register 17Add contents of registers 18 and 19 and put result in register 17
sub $19, $19, $18
Subtract $19 - $18 and put the result back in $19Subtract $19 - $18 and put the result back in $19
3.3
Registering
• MIPS has 32 general-purpose registers
• $0 through $31
47$2
3.3
• Each register holds 32 bits
• 0 to 232 -1 (4 billion) if unsigned
• -231 to +231-1 (-2 billion to +2 billion) if signed
• Most registers can hold any value, for any purpose
• Exception: $0 is always zero!
Register Naming and Conventions• In MIPS, all registers (except $0) can be used for any purpose
desired
• However, there are standard use conventions that make it easier to write software
# Name Purpose$0 $zero Constant zero$1 $at Reserved for assembler$2 $v0 Function return value$3 $v1$4 $a0 Function parameter$5 $a1
$6 $a2$7 $a3$8 $t0 Temporary – Caller-saved$9 $t1$10 $t2$11 $t3$12 $t4$13 $t5$14 $t6$15 $t7
# Name Purpose$16 $s0 Temporary – Callee-saved$17 $s1$18 $s2$19 $s3$20 $s4$21 $s5
$22 $s6$23 $s7$24 $t8 Temporary – Caller-saved$25 $t9$26 $k0 Reserved for OS$27 $k1$28 $gp Global pointer$29 $sp Stack pointer$30 $fp Frame pointer$31 $ra Function return address
Reflections on Registers
• Registers are just “special” memory locations
• A small number of registers, as opposed to a huge number of memory locations
• Because there are a small number of registers, accessing them is fast
• Principle: Smaller is usually faster.
3.3
• Trade-offs
• More registers --> More data in fast memory --> Faster execution
• Fewer registers --> Registers are faster --> Faster execution
• Compromise: 16 to 32 registers works well
Complicated arithmetic
F = (A + B) - (C + D)
Assume: A is in $8 B is in $9 C is in $10 D is in $11 F is in $12
Note: Typically, the compilerassigns variables toregisters
Note: Typically, the compilerassigns variables toregisters
$12 = ($8 + $9) - ($10 + $11)
We don’t have a 5-operandadd/subtract instruction!
Use temporary variables tosolve the problem.
add $13, $8, $9 # $13 <-- A + Badd $14, $10, $11 # $14 <-- C + Dsub $12, $13, $14 # F <-- (A+B) - (C+D)
$13 and $14 aretemporary variables$13 and $14 aretemporary variables
3.3
Getting to the bits of it all
We’ve looked at assembly language (briefly)
The CPU wants bits.
add $13, $8, $9
Assembler
0 8 9 13 0 32
Opcode RS RT RD ShAmt Function
6 bits 5 bits 5 bits 5 bits 5 bits 6 bits
0 = Add $8 $9 $13 0 32=Add
32 bits, total
R-Type InstructionR-Type Instruction
3.4
000000 01000 01001 01101 00000 100000
Staying RegularR-Type instructions all have the same format:
Add has an opcode of ‘0’, a function of ‘32’
The instructions differ only in one bit!The instructions differ only in one bit!
Regularity:
Similar functions should be similar in format.Similar functions should be similar in format.Regularity is a keyto high-performance
3.4
Opcode RS RT RD ShAmt Function
6 bits 5 bits 5 bits 5 bits 5 bits 6 bits
Subtract has an opcode of ‘0’, a function of ‘34’
add $13,$8,$9: 000000 01000 01001 01101 00000 100000
sub $13,$8,$9: 000000 01000 01001 01101 00000 100010
Constants
Many times, an instruction needs to use a constant value• Multiply by 4• Add 3
I-Type instructions all have the same format:
Opcode RS RT Immediate Data
6 bits 5 bits 5 bits 16 bits
8 10 12 4
001000 01010 01100 0000 0000 0000 0100
I-Type InstructionI-Type Instruction
3.8
addimmediate
Instructions with constant data in them are called immediate instructions• addi $12, $10, 4 # Reg. 12 <-- Reg. 10 + 4
Doing Double Duty
• You desire to copy the value in register $8 to $10
• Called a “move” in computer terms
• move $10, $8 #copy register $8 to $10
• Doesn’t exist in MIPS assembly language!
3.4
• add $10, $8, $0 # adds zero and $8, result in $10
• Does the same thing as a move
• Allows the add instruction to serve double duty!• Many instructions have double/triple functions
• sub $8, $0, $8 # negate $8
• addi $12, $0, 4 # load register $12 with value 4
Thanks for all the Memory!When 32 registers just won’t do.When 32 registers just won’t do.
Many times (almost all the time, actually), you can’t fit all of yourdata into 32 registers.
What do you do? Put some (most) of the data in main memory.What do you do? Put some (most) of the data in main memory.
Remember: Smaller is faster. Registers: Small and Fast Memory: Big and Slow In MIPS, all operations (i.e. arithmetic)
are done on registers, only.
Memory is used only for storing whatwon’t fit in registers.
In MIPS, all operations (i.e. arithmetic)are done on registers, only.
Memory is used only for storing whatwon’t fit in registers.
3.3
Loading and StoringSo you’ve got some data in memory. Big deal. You need it in a registerto do anything useful.
You need to load a register with a value from memory.
lw $10, 1000($0) # copy memory location 1000 to $10lw $10, 1000($0) # copy memory location 1000 to $10
Load Word - Loads a whole 32-bit wordLoad Word - Loads a whole 32-bit word This value is added to 1000 - for now, it is zeroThis value is added to 1000 - for now, it is zero
Say you’ve added 1 to register $10 (now it has the value 44). Now you want to put it back in memory again.
You need to store the register’s value back to memory.
sw $10, 1000($0) # copy $10 to memory location 1000 sw $10, 1000($0) # copy $10 to memory location 1000
3.3
32880996431000
2341004
Afterwards, $10 has the value 43Afterwards, $10 has the value 43
44
Aside: Load and Store Architectures• The only way to communicate with memory is
through a LW or SW instruction
• If you want to operate on memory, you have to use at least three instructions (usually)
lw $15, 4500($0) # load M[4500] into $15
add $15, $15, $3 # add $3 to $15
sw $15, 4500($0) # store $15 back into M[4500]
3.3
• It doesn’t have to be this way
• Contrast this with the Motorola 68000• ADD D3, 4500 ; add register D3 to M[4500]
• Is the grass greener on the other side?
• MIPS: Takes more, simpler instructions... RISC
• MC68000: Takes fewer, complex instructions... CISC
Data Structures - ArraysA single-dimensional array (vector) is a simple linear data structure
20002004200820122016202020242028
int A[5]; /* integers are 4 bytes each */
start of array (2004 in this example)A[0]A[1]A[2]A[3]A[4]
For 4-byte integers:Location of A[n] = Start + n*4;
For data items of size s bytes:Location of A[n] = Start + n*s;
Accessing data in memoryAssume that the variable List points to the beginning of an arrayof 32-bit integers.
List=6000 123600032886004
43600816012
456016...
...
Note: Memory addresses refer to 8-bit bytes! We usually reference 32-bit words.All lw/sw instructions must use an address that is a multiple of 4!To get proper index, have to multiply by 4.
Note: Memory addresses refer to 8-bit bytes! We usually reference 32-bit words.All lw/sw instructions must use an address that is a multiple of 4!To get proper index, have to multiply by 4.
Move List[0] into $3:
lw $3, List($0) # $3 <-- List[0]
Move List[1] into $4:
addi $8, $0, 4 # $8 <-- 4lw $4, List($8) # $4 <-- List[1]
addi $8, $0, 16 # $8 <-- 16lw $5, List($8) # $5 <-- List[4]
Move List[4] into $5:
List and contents of $8 are added together to form addressList and contents of $8 are added together to form address
3.3
List[0]List[1]List[2]List[3]List[4]
Load/Store Format• What instruction format do LW and SW have?
• lw $5, 240($9) # load M[240+$9] into $5
• Needs
• Opcode
• Source register ($9)
• Immediate Operand (240)
• Destination register ($5)
Opcodefor LW: 35Opcodefor LW: 35
ThinkRegularity!ThinkRegularity!
3.4
Opcode RS RT Immediate Data
6 bits 5 bits 5 bits 16 bits
35 9 5 240
100011 01001 00101 0000 0000 1111 0000
I-Type InstructionI-Type Instruction
Opcodefor SW: 43Opcodefor SW: 43
• Hmmm, we’ve seen this before....
Assembler directives• Somehow, we’ve got to get data into memory
• User input• Involves system calls (we’ll get to that later)
• Constant data
A.10
• Constant data is data that is in memory before our program starts executing
• Machine-language instructions don’t give much help• The only way is to use Immediate instructions
• The assembler helps us here!• Assembler directives are special commands to the
assembler. The most common directives put data into memory.
.word Assembler Directive
Buffer: .word 01, 02
Label: A name for this memory to go by.Acts as a variable name.
Label: A name for this memory to go by.Acts as a variable name.
.word: Directive to store words in memory here..word: Directive to store words in memory here.
Data to be stored.Data to be stored.
01000000
02000000
Buffer:Buffer+ 4:
lw $12, Buffer($0) # $12 <-- 00 00 00 01addi $10, $0, 4 # $10 <-- 4lw $13, Buffer($10) # $13 <-- 00 00 00 02
Remember: Words are 4 bytes each!Remember: Words are 4 bytes each!
A.10
Loads from Buffer+0 Loads from Buffer+4
The Assembler Location CounterThe assembler keeps track of where to put things by using a location counter. The location counter just points to the memory location to put the “next” item.
buffer1: .word 12buffer2: .word 3, 4, 0x20, 0x5
add $9, $0, $0 firstld: lw $8, buffer1($9)
addi $9, $9, 4 secld: lw $10, buffer2($9)
For this example, assume the location counter starts at 4000
4000:4004:
4020:4024:4028:4032:
4004 4008
4012 4016
Hex Constants a denoted by the “0x” prefix
buffer1 = 4000
buffer2 = 4004
firstld = 4024secld = 4032
Label TableLoc. Ctr.
Data Structures? No, thanks
• Assembly has no concept of “data structures”
• You can access a “variable” using another “variable”
.data
Tonto: .word 0x44, 0x22Tonto2: .word 0x32
.text
main:add $9, $0, $0 # clear $9lw $8, Tonto($9) # put Tonto[0] in $8addi $9, $9, 4 # increment $9lw $10, Tonto($9) # put Tonto[1] in $10addi $9, $9, 4 # increment $9lw $10, Tonto($9) # put Tonto[2] ???? in $10addi $v0,$0,10syscall
Other Memory Assembler Directives
greeting: .asciiz “Resistance is small.”
greeting2: .ascii “You will be informed.”
52 65 73 69greeting:
6C 65 2E 0
... Null-terminatedNull-terminated
59 6F 75 20
65 64 2E --
...greeting2:
A.10
.byte - reserves bytes in memory
.asciiz - reserves Null-terminated ASCII chars
.ascii - reserves ASCII characters (no NULL)
10 12 22 33borg:? ? 1 8
borg: .byte 33, 22, 12, 10, 8, 1
Meeting all your needs for space
Sometimes, we need to allocate (empty) space to be used later.
inputbuffer: .space 100
Allocates 100 bytes of space for an input buffer.
Space allocated this way is just reserved by the assembler.You have to make your own use of it.
addi $12, $0, 6sw $12, inputbuffer($0) # stores 6 in buffer
A.10
Our first program!# This is our first program! Yeah!
.data
Tonto: .word 0x44, 0x22
.text
main:add $9, $0, $0 # clear $9lw $8, Tonto($9) # put Tonto[0] in $8addi $9, $9, 4 # increment $9lw $10, Tonto($9) # put Tonto[1] in $10
addi $v0,$0,10syscall
.data means that data follows .data means that data follows
.text means that code follows.text means that code follows
main: tells SPIM where to startmain: tells SPIM where to start
these two instructions end the programthese two instructions end the program
A.10
Instruction PC R5 R6 R7
1 add $6, $0, $0
2 add $7, $0, $0
3 lw $5, ARRAY($7)
4 add $6, $6, $5
5 addi $7, $7, 4
6 lw $5, ARRAY($7)
7 add $6, $6, $5
8 addi $7, $7, 4
9 lw $5, ARRAY($7)
10 add $6, $6, $5
11 addi $7, $7, 4
12 lw $5, ARRAY($7)
13 add $6, $6, $5
14 addi $7, $7, 4
15 lw $5, ARRAY($7)
16 add $6, $6, $5
17 sw $6, SUM($0)
18 addi $v0, $0, 10
Logic Instructions• and $10, $8, $6 # bitwise and between $8 and $6, result in $10
• Example:• $8 = 0010 0001 1100 0001 0011 1100 1010 0000• $6 = 1101 1110 0011 0001 1111 0000 1100 0001• $10=0000 0000 0000 0001 0011 0000 1000 0000
• or $10, $8, $6 # bitwise or between $8 and $6, result in $10• xor $10, $8, $6 bitwise xor between $8 and $6, result in $10• The above are R-Type instructions• andi $10, $8, 6 # bitwise and between $8 and 6, result in $10
• Example:• $8 = 0010 0001 1100 0001 0011 1100 1010 0000• 6 = 0000 0000 0000 0000 0000 0000 0000 0110• $10=0000 0000 0000 0000 0000 0000 0000 0000
• ori $10, $8, 6 # bitwise or between $8 and 6, result in $10• xori $10, $8, 6 bitwise xor between $8 and 6, result in $10• The above are I-Type instructions
Example
• Write at least 5 ways of clearing a register
• Write at least 4 ways of copying the contents of a register to another register
Pseudoinstructions• Some “missing” instructions are commonly composed of
others
• The assembler “implements” these by allowing the “missing” instructions to be entered in assembly code.
• When machine code is generated, the pseudoinstructions are converted to real instructions.
• Pseudoinstructions are assembler-dependent
• They can be turned-off in SPIM
move $5, $3 add $5, $3, $0
neg $8, $9 sub $8, $0, $9
A.10
li $8, 44 addi $8, $0, 44 or ori $8, $0, 44
SPIM I/O• SPIM I/O uses the SYSCALL pseudoinstruction
• Set up parameters
• Place correct code in $v0
• Execute SYSCALL
To print the value in $t3: move $a0, $t3 li $v0, 1 syscall
To display a stringprompt: .asciiz “hello world” la $a0,prompt li $v0, 4 syscall
Action Code (in $v0) ParametersPrint an Integer 1 $a0 = value to printPrint a String 4 $a0 = location of stringInput an Integer 5 (after syscall) $v0 contains integerInput a String 8 $a0 = location of buffer, $a1 = lengthExit program 10
Boring• Straight-line code is nice,
but boring
• Just arithmetic and loads/stores based on a predetermined sequence
A = B+C
D = B+F
M[18]=D
D = B+F
D>23?
M[22] = D
C = B+A
Y
N
3.5
• Decision-making elements add some spice to the equation
• Control allows programs to make decisions based on their current state
• The most common control structure is the branch
Going placesConsider the GoToConsider the GoTo
if (x == y) q = 13;
if (x != y) GoTo Next;q = 13;
Next: ...
while (y < 2) y = y+1;
Loop: if (y >=2) GoTo End;y = y+1;
GoTo Loop;End: ...
if (p > q) r = 3; else r=2;
if (p>q) GoTo R3;r = 2;GoTo Next;
R3: r = 3;Next: ...
if (condition) GoTo location andGoTo location are all we need
if (condition) GoTo location andGoTo location are all we need
3.5
Branching outif ($9 == $10) GoTo Label;
beq $9, $10, Label
if ($7 != $13) GoTo Next;
bne $7, $13, Next
beq - Branch if EQualbeq - Branch if EQual
bne - Branch if Not Equalbne - Branch if Not Equal
GoTo Exit;
j Exit j - Jump (unconditionally)j - Jump (unconditionally)
Opcode Immediate Data6 bits 26 bits J-Type InstructionJ-Type Instruction
3.5
Branches use I-Type Instruction Format(need two registers and 16-bit data)
Jumps need only an opcode and data -There is a lot more room for the data...
IF-Then Structuresif $x == $y then S1 S2
S1 should be executed if $x == $y is TrueIf $x != $y, or after S1 is executed, S2 is executed
bne $x, $y, False # if $x != $y, skip S1S1 # $x == $y, execute S1
False: S2 # either way we get here, execute S2
3.5
beq $x, $y, True # if $x == $y, then execute S1j False # $x != $y, so exit
True: S1 # $x == $y, execute S1False: S2 # either way we get here, execute S2
If you can’t express the condition as a negative, try this:
IF-Then-Else Structures
if $x == $y then S1 else S2 S3
S1 should be executed if $x == $y S2 should be executed if $x != $y After executing S1 or S2, execute S3
beq $x, $y, IF # if $x == $y, goto S1, skip S2S2 # $x != $y, execute S2j Finish # now execute S3
IF: S1 # $x == $y, so execute S1Finish: S3 # either way, we do S3 afterwards
3.5
More Complicated If-Then-Else structures
if $x == $y and $z == $w then S1 else S2 S3
S1 should be executed if both $x == $y and $z == $w S2 should be executed if either $x != $y or $z != $w After executing S1 or S2, execute S3
The simplest way to figure out complex if-then-else structures is to first write the conditions, then all the statements and finally figure out the branches and jumps
STEP 1: conditionsbne $x, $y, ____
bne $z, $w, ____
STEP 2: statementsbne $x, $y, ____
bne $z, $w, ____
S1S2S3
STEP 3: branches bne $x, $y, false bne $z, $w, false S1 j skipfalse: S2skip: S3
STEP 1: conditionsbne $x, $y, ____
bne $z, $w, ____
STEP 2: statementsbne $x, $y, ____
bne $z, $w, ____
S1S2S3
The simplest way to figure out complex if-then-else structures is to first write the conditions, then all the statements and finally figure out the branches and jumps
STEP 1: conditionsbne $x, $y, ____
bne $z, $w, ____
STEP 2: statementsbne $x, $y, ____
bne $z, $w, ____
S1S2S3
STEP 1: conditionsbne $x, $y, ____
bne $z, $w, ____
STEP 3: branches bne $x, $y, false bne $z, $w, false S1 j skipfalse: S2skip: S3
STEP 1: conditionsbne $x, $y, ____
bne $z, $w, ____
STEP 1: conditionsbne $x, $y, ____
bne $z, $w, ____
STEP 2: statementsbne $x, $y, ____
bne $z, $w, ____
S1S2S3
Example
if $x == $y or $z == $w then S1 else if $x == $z or $y == $w then S2 else S3
STEP 1: conditionsbne $x, $y, ____
bne $z, $w, ____
STEP 3: branches beq $x, $y, then1 beq $z, $w, then1 beq $x, $z, then2 beq $y, $w, then2 j skipthen1: S1 j skip
then2: S2
skip: S3
STEP 1: conditionsbne $x, $y, ____
bne $z, $w, ____
STEP 1: conditionsbeq $x, $y, ____
beq $z, $w, ____
beq $x, $z, ____
beq $y, $w, ____
STEP 2: statementsbeq $x, $y, ____
beq $z, $w, ____
beq $x, $z, ____
beq $y, $w, ____
S1S2S3
Interlude: Comments on Comments
• Code should be thoroughly commented• Code may be modified by different programmers• Code may be reused a long time after writing it
• There are two types of commenting style depending on the reader of the code the comments are intended for• Comments that explain what the instruction does
• Typical for programming language books and lecture notes• The purpose is to learn the language• Worthless if used in a real program
• Comments that explain the logic behind the instruction• Typical for real programs, assumes reader knows language• The purpose is to understand the program• Not helpful for learning the language
• Examples:• addi $7, $7, 4 #add 4 to R7, R7<-R7+4 #incrementing address• lw $5, ARRAY($7) #R5 <- [ARRAY+4] #fetching next ARRAY
#element
While Loops
while $x == $y do S1
Execute S1 repeatedly as long as $x == $y is true
Repeat: bne $x,$y, Exit # exit if $x != $y is FalseS1 # execute body of loopj Repeat # do it all over again
Exit: # end of the loop
3.5
Repeat: S1 # execute body of loopbeq $x,$y, Repeat # do it again if $x == $y
Exit: # end of the loop
Warning: The following loop always executes at least once, no matter what $x and $y are:
For Loopsfor i = $start to $finish {S1}S2
Execute S1 for all values from $start to $finish (step of 1)
move $t0, $start # copy start to i ($t0)Loop: bgt $t0, $finish, done # if i > finish, then we’re done - do S2
S1 # execute S1addi $t0, $t0, 1 # increment countj Loop # go again
done: S2
3.5
Use temporary, $t0 to hold i
Note: bgt doesn’t really exist - more on that later...
Other conditions
slt $4, $10, $11
Set $4 = 1 if ($10 < $11), otherwise $4 = 0Set $4 = 1 if ($10 < $11), otherwise $4 = 0
if ($7 < $8) then $15 = 3;
slt $1, $7, $8 # $1 <-- ($7 < $8)beq $1, $0, GoOn # If not less than, go onaddi $15, $0, 3 # ($7 < $8), so $15 <-- 3
GoOn:
Set on Less ThanSet on Less Than
if ($12 >= $3) then $4 = $2;
slt $1, $12, $3 # $1 <-- ($12 < $3)bne $1, $0, GoOn # If less than, go onadd $4, $2, $0 # ($12 >= $13), so $4 = $2
GoOn:
3.5
Example: $7=4, $8=9
$1 = 1 ( $7 < $8)
$1 0, Don’t branchSet $15 to 3
Example: $7=4, $8=2
$1 = 0 ( $7 > $8)
$1 == 0, BranchGoOn ($15 not changed)
Example: $12=4, $3=2
$1 = 0 ( $12 > $3)
$1 == 0, Don’t branchSet $4 to 2
Pseudoinstructions for branches• Branches can be nasty to figure out
• SPIM provides several pseudoinstructions for branches
blt $3, $4, dest slt $1, $3, $4bne $1, $0, dest
bgt $3, $4, dest slt $1, $4, $3bne $1, $0, dest
$3 > $4 same as$4 < $3$3 > $4 same as$4 < $3
A.10
ble $3, $4, dest slt $1, $4, $3beq $1, $0, dest
bge $3, $4, dest slt $1, $3, $4beq $1, $0, dest
$3 >= $4 is the opposite of $3 < $4$3 >= $4 is the opposite of $3 < $4
$3 <= $4 is the opposite of $3 > $4$3 <= $4 is the opposite of $3 > $4
Branch limitations• A conditional branch (BEQ, BNE) uses an I-type
Instruction
• Allows a 16-bit immediate operand
• 216 = 64K Locations is too small
3.8
• Notice that most branches don’t go very far away (back to the beginning of a loop, etc.)
• Use PC-relative addresses for branches• Immediate operand is a displacement in 4-byte
words from the next instruction• May be positive (forward branches) or negative
(backwards branches)
Branch example
loop: bgt $t0, $t1, biggerlw $s0, 0($t0)addi $t0, $t0, 1beq $s0, $s1, loop
bigger: move $s2, $t0
8000 loop: slt $1, $8, $98004 bne $1, $0, bigger
5 1 0 +380040 8 9 1 0 428000
3.8
35 8 16 080088 8 8 180124 16 17 -580160 8 0 18 0 328020
bigger: + 3 instructions
8020 bigger: add $18, $8, $0
8008 lw $16, 0($8)8012 addi $8, $8, 18016 beq $16, $17, loop
loop: -5 instructions
+3
-5
Branches: offset is in instructions fromthe instruction following the branch
Note: Negative numbers require 2’s complement
Jump Addressing
3.8
• Jumps use a J-type instruction and have a 26-bit offset
• A lot more range than 16-bit branches
• Allows a range of 226=64M possibilites
2000: j target
0 2 4 1 0 3220042 5012000
2004: target: add $1, $2, $4501 = 2004/4Example:
• Because the range is so much larger, jumps use absolute addressing
• Absolute addressing just specifies the address of the jump target
• Since all instructions have addresses that are multiples of 4, we only need to put the address divided by 4 in the instruction field• Actual byte address is obtained by multiplying by 4• Allows a range of 64M instructions = 256M bytes
Jumping based on Registers
• Jumps change the PC to a fixed location
• j OverThere
• Always goes to the same place
JR - Jump RegisterJR - Jump Register
3.5
• Is there a way to jump to a place to be determined by the program?
• Put the address to go to in a register• addi $14, $0, 10000
• Jump to the address contained in that register• jr $14
LUI• Registers can hold 32 bits, but we can only load in 16-bit
immediate data
• LUI - Load Upper Immediate
• Loads constant into bits 31-16 of register
• Bits 15-0 become zero
lui $8, 0x1A2Bli $8, 0x3C4D
Warning: Don’t use addi for the second instruction; use LI or ORI. (Sign Extension)Warning: Don’t use addi for the second instruction; use LI or ORI. (Sign Extension)
3.8
$8: ----31 16 15 0
----1A2B 0000 3C4D
Put the constant 0x1A2B3C4D in register $8
We can let the assembler do the work:li $8, 0x1A2B3C4D will be converted to these two instructions
We can let the assembler do the work:li $8, 0x1A2B3C4D will be converted to these two instructions
Getting around branch limitationsBranches have a limit of +/- 215 instructions - How can we branch further?
Use the larger range of the jump instruction:
1000: beq $s0,$t1,far1004: sub $s2, $v0, $a0…500000: far: add $t1, $t2, $t3
1000: bne $s0,$t1,stay1004: j far1008: stay: sub $s2, $v0, $a0…500000: far: add $t1, $t2, $t3
3.8
Can’t branch that far...
ExampleInstruction R5 R6 R7 Addr:Data
1 add $6, $0, $0 8000: 0x32 addi $7, $0, 8 8004: 0x43 lw $5, ARRAY($7) 8008: 0x54 add $6, $6, $5 800C5 addi $5, $0, 0 80106 lui $5, 0x5 80147 be $5, $0, EXIT 80188 slt $5, $0, $6 801C9 li $7, 0x8000 802010 lw $5, 0($7)
11 and $5, $5, $7
12 bgt $5, $6, EXIT
13 li $7, 0xC
14 sw $5, 8000($0)
15 sw $6, 8000($4)
16 j EXIT
17 sw $7, 8014($0)
18 EXIT:
The Stack• A stack is a one-dimensional data structure• The stack segment of a program is used for temporary storage of data
and addresses• Items are added to and removed from one end of the structure using a
"Last In - First Out" technique (LIFO)• The top of the stack is the last addition to the stack• Every program has three segments of memory assigned to it by the
operating system• the “text” segment where the machine language code is stored, • the “data” segment where space is allocated for global constants
and variables, • the stack segment.
• The stack segment is provided as an area where • parameters can be passed,• local variables for functions are allocated space, • return addresses for nested function calls and recursive functions
are stored• The operating system initializes register 29 ($sp) in the register file to
the base address of the stack area in memory • The stack grows toward lower addresses
The Stack
• MIPS has no special push and pop instructions
• However the following instructions are equivalent
• PUSH
addi $sp, $sp, -4 #decrement stack pointer
sw $5, 0($sp) #save $5 to stack
• POP
lw $5, 0($sp) #load from stack to $5
addi $sp, $sp, 4 #increment stack pointer
Subroutines
• Subroutines allow common program portions to be reused
• int CalcInterest(int principle, int time) { ... }
• y = CalcInterest(1000, 10)
• z = CalcInterest(1000, 15)
3.6
• When calling a subroutine, you must:
• Set up any parameters
• Save the current position so the program will know where to return to
• Jump to the location of the subroutine
Jumpin’ and Linkin’• JAL - Jump and Link
• Saves the return address• Write address of next instruction in $31 ($ra)
• Jumps to the address specified and keeps going
100: jal CALC104: sub $4, $4, $2
...342: CALC: add $14,$15,$2346: mult $14, $2
...368: jr $ra
Call the Calc subroutineSave addr. of next instr. in $ra ($31)
Call the Calc subroutineSave addr. of next instr. in $ra ($31)
End of Subroutine.Return to Return Address in $ra
End of Subroutine.Return to Return Address in $ra
$ra
Start of SubroutineStart of Subroutine
3.6
104
Instruction R5 R6 R7 Addr:Data1 add $6, $0, $0 8000: 0x32 addi $7, $0, 8 8004: 0x43 lw $5, ARRAY($7) 8008: 0x54 add $6, $6, $5 800C5 addi $5, $0, 0 80106 jl CALC 80147 be $5, $0, EXIT 80188 slt $5, $0, $6 801C9 li $7, 0x8000 802010 j EXIT
11 CALC: and $5, $5, $7
12 li $7, 0xC
13 sw $5, 8000($0)
14 sw $6, 8000($4)
15 sw $7, 8008($0)
16 jr $ra
17 sw $7, 8014($0)
18 EXIT:
Passing Parameters• Most subroutines have parameters to make them
more interesting...
• Z = Addemup(A,B,C)
3.6
• In order to pass parameters, we must place the parameters in registers before calling the subroutine
• $a0, $a1, $a2, $a3 used for these ($4 - $7)
• $a0 <-- A, $a1 <--B, $a2 <--C
• Before calling a routine, copy all parameters to the appropriate registers
• Return values are put in $v0, $v1 ($2, $3)
• $v0 <-- Z
• After subroutine finished, copy return values back
Thoughts about MIPS programming
• Write the program in C/C++ first
• Break it into procedures as appropriate
• Convert the program to assembly language
• Start out simple
• Get basic parts working before adding error checking, etc.
• Don’t forget: Words are 4 bytes
• Use pseudoinstructions when applicable
Example
• Write a MIPS assembly program that finds the sum of 5 numbers found in consecutive memory locations starting at array and stores it in memory location sum.
.dataARRAY: .word 3, 5, 7, 9, 2 #random valuesSUM: .word 0 #initialize sum to zero
.textmain: addi $6, $0, 0 #set loop counter to 0 addi $9, $0, 5 #cannot compare with 5 directly
addi $7, $0, 0 #set pointer to zeroaddi $8, $0, 0 #set $8 (sum temp) to zero
REPEAT: lw $5, ARRAY($7)add $8, $8, $5addi $7, $7, 4 #increment pointeraddi $6, $6, 1 #increment loop counterbne $6, $9, REPEATsw $8, SUM($0) #copy sum to memory
addi $v0, $0, 10 #exit programsyscall
Example (improved version)• We can improve the previous program if we consider that comparing with zero is free in
MIPS, so we can count down to zero instead of up to five. This saves one instruction and one register
.dataARRAY: .word 3, 5, 7, 9, 2 #random valuesSUM: .word 0 #initialize sum to zero
.textmain: addi $6, $0, 5 #initialize loop counter to 5
addi $7, $0, 0 #initialize array index to zeroaddi $8, $0, 0 #set $8 (sum temp) to zero
REPEAT: lw $5, ARRAY($7) #R5 = ARRAY[i]add $8, $8, $5 #SUM+= ARRAY[I]addi $7, $7, 4 #increment index (i++)addi $6, $6, -1 #decrement loop counterbne $6, $0, REPEAT #check if 5 repetitionssw $8, SUM($0) #copy sum to memory
addi $v0, $0, 10 #exit programsyscall
Example (improved v2)
• We can eliminate the loop counter and use the index to the array as counter if we consider the end value 4*5=20.This saves one more instruction
.dataARRAY: .word 3, 5, 7, 9, 2 #random valuesSUM: .word 0 #initialize sum to zero
.textmain: addi $6, $0, 20 #set loop counter to 20
addi $7, $0, 0 #set pointer to zeroaddi $8, $0, 0 #set $8 (sum temp) to zero
REPEAT: lw $5, ARRAY($7)add $8, $8, $5addi $7, $7, 4 #increment pointerbne $6, $7, REPEATsw $8, SUM($0) #copy sum to memory
addi $v0, $0, 10 #exit programsyscall
Example 2• Modify the program to read five numbers from the keyboard and then
move them to location ARRAY
.dataARRAY: .space 20 #reserving space for 5 numbersSUM: .word 0 #initialize sum to zeroPROMPT: .asciiz "Please enter five numbers"RESULT: .asciiz "The sum of the numbers you entered is:"
.textmain: addi $6, $0, 5 #set loop counter to 5
addi $7, $0, 0 #set pointer to zeroaddi $8, $0, 0 #set $8 (sum temp) to zerola $a0,PROMPT #print prompt
li $v0, 4 syscallINPUT: li $v0, 5 syscall sw $v0, ARRAY($7) #moving input to array addi $7, $7, 4 #increment pointer addi $6, $6, -1 #decrement loop counter
bne $6, $0, INPUT
Example 3 (1/3)• Write a MIPS assembly program that finds the maximum of 5 positive
numbers read from the keyboard, stores it to memory location max and prints the result on the screen. Use functions.
.dataARRAY: .space 20 #20 bytes for the 5 numbersMAX: .word 0 #initialize sum to zeroPROMPT: .asciiz "Please enter five numbers"RESULT: .asciiz "The maximum of the numbers you entered
is:".text
main: la $a0,PROMPT #setup call to print prompt jal PRINT #call to print message jal READ #call to input function, reads from keyboard jal FINDMAX #call to findmax function la $a0,RESULT #setup call to print result jal PRINT move $a0, $8 #setup value to print jal OUTPUT #call to output function, prints to screen
addi $v0, $0, 10 #exit programsyscall
Example 3 (2/3)
PRINT: li $v0, 4 #print prompt
syscall
jr $ra
READ: addi $6, $0, 5 #set loop counter to 5, setup input function
addi $7, $0, 0 #initialize pointer
REPEAT: li $v0, 5
syscall
sw $v0, ARRAY($7) #moving input to array
addi $7, $7, 4 #increment pointer
addi $6, $6, -1 #decrement loop counter
bne $6, $0, REPEAT
jr $ra
Example 3(3/3)
FINDMAX:addi $6, $0, 5 #set loop counter to 5addi $7, $0, 0 #set pointer to zeroaddi $8,$0, 0 #initial maximum
REPEAT: lw $5, ARRAY($7)bge $8, $5, SKIP #if $8 > $5, keep current maximummove $8, $5 #else new maximum
SKIP: addi $7, $7, 4 #increment pointeraddi $6, $6, -1 #decrement loop counterbne $6, $0, REPEATsw $8, MAX($0) #copy MAX to memory
jr $ra
OUTPUT: li $v0, 1 syscall jr $ra
Example 4
Write a function to scan an array “X” of 10 bytes counting how many bytes are ASCII codes for:
• a. upper case letters - U
• b. lower case letters - L
• c. decimal digits - D
.dataARRAY: .asciiz “df12o@pZ4X” #data for testU: .word 0 #initialize sum to zeroL: .word 0D: .word 0
ASCII Table
.text
main: addi $5, $0, 10 #set loop counter to 5
addi $6, $0, 0 #set pointer to zero
add $7, $0, $0 #U
add $8, $0, $0 #L
add $9, $0, $0 #D
li $10, 48 #0
li $11, 57 #9
li $12, 65 #A
li $13, 90 #Z
li $14, 97 #a
li $15, 122 #z
REPEAT: lb $16, ARRAY($6)blt $16, $10, SKIP # if ASCII<’0’, neither
bgt $16, $11, LETTER #else if ASCII>’9’, not a number addi $9, $9, 1 #else ‘0’<ASCII<‘9’, it’s a number j SKIP LETTER: blt $16, $12, SKIP #if 9<ASCII<‘A’, neither bgt $16, $13, LOWER #else if ASCII>’Z’, not uppercase addi $7, $7, 1 #else 9<ASCII<‘A’, uppercase j SKIP
LOWER: blt $16, $14, SKIP # if ‘Z’<ASCII<’a’, neitherbgt $16, $15, SKIP #else if ASCII>’z’, neither
addi $8, $8, 1 #else ‘a’<ASCII<’z’, j SKIP SKIP: addi $6, $6, 1 bne $5, $6, REPEAT
sw $7, U($0)
sw $8, L($0)
sw $9, D($0)
addi $v0, $0, 10 #exit program
syscall
Saving registers and passing parameters through the stack
• Subprograms are typically written by different programmers
• Each programmer does not know which registers the others are using
• Could overwrite each others data!
• Don’t know where to find arguments and return results
Example of overwriting data by mistake
main: addi $t0, $0, 5 #main program needs 5 in $t0
jal FUNC1
add $t0,$t0, $t1 #now $t0 has wrong value
FUNC1: addi $t0, $0, 10 #FUNC overwrites $t0
…
jr $ra
Solution: save data you need on the stack
main: addi $t0, $0, 5 #main program needs 5 in $t0
addi $sp, $sp, -4 #decrement stack pointer
sw $t0, 0($sp) #save $t0 to stack
jal FUNC1 #before calling FUNC1
lw $t0, 0($sp) #load from stack to $t0
addi $sp, $sp, 4 #increment stack pointer
add $t0,$t0, $t1 #now $t0 has correct value
FUNC1: addi $t0, $0, 10 #FUNC can now use $t0
…
jr $ra
Passing parameters
• Let’s create a function that adds two numbers
• In high-level languages this would be x=SUM(a,b)
• Where can a, b and x be found in assembly?
main:
jal SUM
SUM: add $??, $??, $?? #SUM must know the registers
…
jr $ra
Solution: Pass a, b and x through the stack
main: addi $sp, $sp, -4 #decrement stack pointersw $t0, 0($sp) #push a=$t0 to stackaddi $sp, $sp, -4 #decrement stack pointersw $t0, 0($sp) #push b=$t1 to stack
jal SUM
lw $t0, 0($sp) #load from stack to x=$t0addi $sp, $sp, 4 #increment stack pointer
SUM: lw $t0, 0($sp) #load from stack to $t0=aaddi $sp, $sp, 4 #increment stack pointer
lw $t1, 0($sp) #load from stack to $t1=baddi $sp, $sp, 4 #increment stack pointer
add $t1, $t0, $t1 #no need to know the registers
addi $sp, $sp, -4 #decrement stack pointersw $t1, 0($sp) #push x=$t1 to stack jr $ra
Example 5
• Write a program that loads a 20-byte string from memory stored in memory location MSG, converts lowercase letters to uppercase and vice versa, stores the modified string in memory location MSG2 and prints it on the screen.
.data
MSG: .asciiz “#8puIth45FaSdf12o@pZ” #data for test
MSG2: .space 20 #reserve 20 bytes
.textmain: addi $5, $0, 20#set loop counter to 20
addi $6, $0, 0 #set pointer to zeroli $12, 65 #ASCII value of Ali $13, 90 #ASCII value of Zli $14, 97 #ASCII value of ali $15, 122 #ASCII value of z
loop: lb $16, MSG($6)blt $16, $12, SKIP #ASCII<‘A’, do nothing
bgt $16, $13, LOWER #else if ASCII>’Z’, not uppercase jal TO_LOWER #else uppercase j SKIP
LOWER: blt $16, $14, SKIP # if ‘Z’<ASCII<’a’, neitherbgt $16, $15, SKIP #else if ASCII>’z’, neither
jal TO_UPPER #else ‘a’<ASCII<’z’, SKIP: jal STORE
addi $6, $6, 1 #increment pointer bne $5, $6, loop
jal PRINTaddi $v0, $0, 10 #exit programsyscall
TO_LOWER: addi $16, $16, 32 #add offset between upper and lower
jr $ra
TO_UPPER: addi $16, $16, -32 #subtract offset between upper and lower
jr $ra
STORE: sw $16, MSG2($6) #storing converted number to MSG2
jr $ra
PRINT: la $a0, MSG2 #putting address of MSG2 to a0 to print
li $v0, 4 #print string system call
syscall
jr $ra