Chapter 3: Instructions
description
Transcript of Chapter 3: Instructions
1
Chapter 3: Instructions
CS 447Jason D. Bakos
2
Assembly Language Instructions
• We’re going to use the MIPS R2000 instruction set for the projects in this course
• Review: Assembly language instructions are English words that represent binary machine language instructions
3
Arithmetic/Logical Instructions
• Arithmetic instructions are composed of an operation and three registers– <op> <destreg> <operand1> <operand2>– There are 32 32-bit general-purpose integer registers
that we can use (R0 is hardwired to value 0 for A/L operands)
– Ex: add $1, $2, $3• When writing assembly language programs, comments can
be added after any instruction by using the ‘#’ character• Some architectures only use 2 registers
– The result is stored in the first operand register– Some of our instructions will use this convention
• Appendix A in the textbook lists all
4
Immediate Arithmetic/Logical Instructions
• Most arithmetic/logical instructions have an “immediate” version– Immediate instructions have an ‘i’ at the end of the
instruction name– Immediate instructions allow us to specify an
immediate/constant/literal in lieu of a register operand
– Ex: add $1, $2, 16– We only have 16-bits for the immediate, so we can
only represent 216 unique values– Use decimal numbers for the immediate value in the
assembly-language instruction
5
A/R Instructions
• MIPS R2000 A/L-instructions (complete)– add, addu, addi, addiu– and, andi– div, divu (two registers)– mult, multu (two registers)– nor– or, ori– sll, sllv, sra, srav, srl, srlv– sub, subu– xor, xori
6
Pseudoinstructions
• Pseudoinstructions are assembled into more than 1 machine instruction– There’s no real machine instruction for them– Ex. abs rdest, rsrc– Assembles into three instructions
• move the contents of rsrc into rdest• if rdest is greater than 0, skip over the next instruction
– We haven’t covered conditional branches yet• subtract rdest from 0
– Appendix A specifies which are pseudoinstructions
7
Design Considerations
• Making most arithmetic instructions have 3 operands simplifies the hardware– This is a design decision– Having a variable number of operands would greatly
complicate the hardware• Limiting ourselves to 32 registers is also a
design decision to keep things on the processor die smaller– Influences clock cycle time– Gives us more real estate for other things on our
core• Less registers, less decoding logic, etc.
8
Registers• MIPS assembly language also has symbolic names for the registers
– $0 => constant 0– $1 => $at (reserved for assembler)– $2,$3 => $v0,$v1 (expression evaluation and results of a function)– $4-$7 => $a0-$a3 (arguments 1-4)– $8-$15 => $t0-$t7 (temporary values)
• Used when evaluating expressions that contain more than two operands (partial solutions)
• Not preserved across function calls– $16-$23 => $s0->$s7 (for local variables, preserved across function calls)– $24, $25 => $t8, $t9 (more temps)– $26,$27 => $k0, $k1 (reserved for OS kernel)– $28 => $gp (pointer to global area)– $29 => $sp (stack pointer)– $30 => $fp (frame pointer)– $31 => $ra (return address, for branch-and-links)
9
Memory and Load/Store Instructions
• As we’ve already seen, a processor can only use data stored in its registers as operands and targets for computation
• Typically, before computation can be performed, data must be loaded from main memory
• After the computation is complete, the results must be stored back to main memory
10
Memory
• Computer memory is byte-addressed but the MIPS architecture requires alignment of loads and stores on the 32-bit (4 byte/word) boundary– This means that all memory references
must be an even multiple of 4• When addressing 4-byte words, you
need to provide the address of the lowest-addressed byte in the word
11
Load/Store Instructions
• Most commonly used:– lw, sw, lh, sh, lb, sb, la
• Use:– lw <rdest>, address– address can be represented as:
• symbolic address (that you declare in SPIM)• symbolic address with register index• decimal_offset($basereg)
– This is the way that the instruction is translated
– loads/stores from contents of $basereg+decimal_offset
12
Load/Store Instructions
• SPIM treats loads and stores with symbolic addresses as pseudoinstructions– loads the address of the data segment as an
immediate into $1• lui $1, 4097
– data starts at hex address 10010000– If an index register is provided, adds the contents of
the index reg to $1• addu $1, $1, rindex
– loads 0($1) into rdest• lw rdest, offset_of_variable($1)• This is an example of base-displacement addressing
• This is why R1 is reserved when you write your programs
13
Load/Store Instructions
• When loading or storing halfwords and bytes, the address points to a aligned word– The halfword would be the LOWER (least
significant) halfword of the word that the address is pointing to
– The byte world be the LOWEST (least significant) byte of the word being that the address is pointing to
14
Constant-Manipulating Instructions
• lui rt, imm– Load the immediate imm into the upper
halfword of register rt– The lower bits are set to 0
• li rt, imm– Load the imm into the lower halfword of
register rt– The upper bits are set to 0
15
Encoding Instructions
• The MIPS architecture has a 32-bit binary instruction format for each class of instruction– A/L, constant manip, comparison, branch,
jump, load/store, data movement, floating-point
• Even though we’ve only covered 3 of these classes, let’s look at how we encode the instructions we’ve learned…
16
Encoding/Translating A/L Instructions
• First (most significant, left-most) 6-bits of ALL instructions is the op-code– The opcode defines the instruction– Doesn’t this only give us 26=64 different
instructions?• Yes! But all A/L instructions, excluding the ones
which have immediates, has an opcode of 0 but has a 6-bit field at the end of the instruction that specifies the operation
17
Encoding/Translating A/L Instructions
• Non-immediate A/L instructions:– 6 bits – opcode (usually 0)– 5 bits – rs (operand 1)– 5 bits – rt (operand 2)– 5 bits – rd (destination)– 5 bits – 0’s or shift amount– 6 bits – operation code
18
Encoding/Translating A/L Instructions
• Immediate A/L instructions– 6 bits – opcode (now unique)– 5 bits – rs (operand 1)– 5 bits – rt (destination)– 16 bits – immediate (understood to be 0-
extended)
19
Encoding/Translating Load/Store Instructions
• 6 bits – opcode• 5 bits – rs (base register)• 5 bits – rt (load from/store to)
– Sometimes the whole register isn’t used• Half words and bytes
• 16 bits – offset
20
Encoding/Translating Constant-Manip. Instructions
• 6 bits – opcode• 5 bits – 0’s• 5 bits – rt dest. register
– Half of this register will be assigned 0’s• 16 bits – immediate
21
Examples• Let’s compile the following C++ code segment into assembly code:
– z=(a*b)+(c/d)-(e+f*g);– lw $s0,a
lw $s1,bmult $s0,$s1mflo $t0 # new instructionlw $s0,clw $s1,ddiv $s0,$s1mflo $t1add $t0,$t0,$t1lw $s0,elw $s1,flw $s2,gmult $s1,$s2mflo $t1add $t1,$s0,$t1sub $t0,$t0,$t1sw $t0,z
22
Examples
• Note: There were many ways we could have compiled the C++ statement
• Now let’s assemble the first three instructions to machine code– Assume the variables are all stored as
words and are stored sequencially, starting with a, from the start of the data segment…
23
Examples
• lw $s0,a– We know s0 is $16– There are a few different ways we can do
this, too…– First, we need to convert this instruction to
a small series of instructions…– lui $1,4097 # 4097 is 1001 in hex
lw 16,0($1) # 0 offset because a is first var…00111100000000010001000000000001 => 3C01100110001100000100000000000000000000 => 8C100000
24
Examples
• mult $s0, $s1– 00000010000100010000000000011000 => 02110018
25
Branch/Jump Instructions• Branch and jump instructions are needed for program control
– if-statements (conditionals)– loops– procedure calls
• Most common:– b <label> -- unconditional branch
• label is a memory address (we can be symbolic ones, of course)
– beq, bgez, bgezal, bgtz, blez, etc.• Conditional branches, where we’re comparing a register to 0 or
two registers to determine if we’re going to branch or not• Also have al (and-link) variants, that link a return address
(instruction following branch) into $31 so we can return• Branch targets are 16-bit immediate offset
– offset in words… it is shifted to the left 2 bits to get byte length
26
Branch/Jump Instructions
– j, jal• Unconditionally branches to a 26-bit pseudodirect
address (not offset)– jalr, jr
• Unconditionally branches to an address stored in a register
27
Encoding/Translating Branch/Jump Instructions
• See Appendix A– These are very similar to the encoding we
covered before
28
Data Movement and Comparison Instructions and
Their Encoding• I’m going to leave the study of these
instructions (from Appendix A) up to you as an exercise!
29
Examples
• if ((a>b)&&(c=d)) e=0; else e=f;lw $s0,alw $s1,bbgt $s0,$s1,next0b nope
next0: lw $s0,clw $s1,dbeq $s0,$s1,yup
nope: lw $s0,fsw $s0,eb out
yup: xor $s0,$s0,$s0sw $s0,e
out: …
30
Examples
• Again, there are many other ways we could have tackled this…
• You will eventually come up with your own strategies for “compiling” the types of constructs you want to perform…
31
Examples
• How about a for loop?• for (i=0;i<a;i++) b[i]=i;
lw $s0,axor $s1,$s1,$s1
loop0: blt $s1,$s0,loop1b outsll $s2,S1,2
loop1: sw $s1,b($s2)addi $s1,$s1,1b loop0
out: …
32
Examples
• How about a pretest while loop?• while (a<b) {
a++;}
lw $s0,alw $s1,b
loop0: blt $s0,$s1,loop1b out
loop1: addi $s0,Ss0,1sw $s0,ab loop0
out: …
33
Examples
• How about a posttest while loop?• do {
a++;} while (a<b);
lw $s0,alw $s1,b
loop0: addi $s0,$s0,1sw $s0,ablt $s0,$s1,loop0…
34
Procedure Calls
• How about a procedure call?– The full-blown C/Pascal recursive procedure
call convention is beyond the scope of this class, so we’ll skip it for now…
– This is described in detail in Appendix A• You can arbitrarily implement your own
procedure call convention…
35
Procedure Calls
• Say we want to write a procedure that computes the factorial of a number, like this:int factorial (int val) {
int temp=val;while (val)
temp*=(--val);return temp;
}
36
Procedure Calls
• Let’s adopt the following simple convention:– We’ll pass the arguments through $a0-$a3
• Only allows for up to 4 arguments– We’ll set our return value in $v0– The return address will be stored in $ra
• This limits us to 1-level of procedure calls– We’ll assume the callee (procedure) will save
registers $s0-$s7 starting at memory address FF000000 when it’s called, and restore the registers before it returns
• This may not be necessary for all procedures
37
Procedure Calls
• So here’s our procedure…factorial: lui $t1,0xFF00
sw $s0,0($t1)sw $s1,4($t1)…sw $s7,28($t1)move $s0,$a0 # new instructionmove $s1,$a0
loop0: bgtz $s0,loop1b out
loop1: mult $s0,$s1mflo $s1subi $s0,$s0,1b loop0
out: move $v0,$s1lw $s0,0($t1) # load back registers…jr $31
38
Procedure Calls
• In order to call our procedure…– load a value into $a0– bal factorial– look in $v0 for the result!
39
I/O
• Doing I/O with SPIM is also described in Appendix A, but we’re going to use the system calls that are set up for us to do I/O…
40
I/O
• SPIM provides some operating system services through the syscall instruction
• To use the system calls:– load system call code (from pg. a49) into
$v0 and argument into $a0…– return values in $v0 (or $f0 for fp results)
41
Example I/O
str:.asciiz “the answer = “.textli $v0,4la $a0, strsyscallli $v0,1la $a0,5syscall
(Refer to page A-49)