• 沒有找到結果。

$t0:

−32768 < offset < 32767

Byte Load and Store

MIPS registers are 32 bits (4 bytes). Loading a byte into a register either clears the top three bytes or

sign-extends them.

42: F0 42($0)

$t0, lbu

000000F0

$t0:

42: F0 42($0)

$t0, lb

FFFFFFF0

$t0:

The Endian Question

MIPS can also load and store 4-byte words and 2-byte halfwords.

The endian question:

when you read a word, in what order do the bytes appear?

Little Endian: Intel, DEC, et al.

Big Endian: Motorola, IBM, Sun, et al.

MIPS can do either SPIM adopts its host’s convention

Big Endian

byte 0 byte 1 byte 2 byte 3

31 0

Little Endian

byte 3 byte 2 byte 1 byte 0

31 0

Testing Endianness

.data # Directive: ‘‘this is data’’

myword:

.word 0 # Define a word of data (=0) .text # Directive: ‘‘this is program’’

main:

la $t1, myword # pseudoinstruction: load address li $t0, 0x11

sb $t0, 0($t1) # Store 0x11 at byte 0 li $t0, 0x22

sb $t0, 1($t1) # Store 0x22 at byte 1 li $t0, 0x33

sb $t0, 2($t1) # Store 0x33 at byte 2 li $t0, 0x44

sb $t0, 3($t1) # Store 0x44 at byte 3 lw $t2, 0($t1) # 0x11223344 or 0x44332211?

j $ra

Alignment

Word and half-word loads and stores must be aligned:

words must start at a multiple of 4 bytes;

halfwords on a multiple of 2.

Byte load/store has no such constraint.

lw $t0, 4($0) # OK

lw $t0, 5($0) # BAD: 5 mod 4 = 1 lw $t0, 8($0) # OK

lw $t0, 12($0) # OK lh $t0, 2($0) # OK

lh $t0, 3($0) # BAD: 3 mod 2 = 1 lh $t0, 4($0) # OK

Jump and Branch Instructions

Jump and Branch Instructions

j Jump

jal Jump and link jr Jump to register jalr Jump and link register beq Branch on equal bne Branch on not equal

blez Branch on less than or equal to zero bgtz Branch on greater than zero

bltz Branch on less than zero

bgez Branch on greater than or equal to zero bltzal Branch on less than zero and link

bgezal Branch on greter than or equal to zero and link

Jumps

The simplest form, j mylabel

# ...

mylabel:

# ...

sends control to the instruction at mylabel. Instruction holds a 26-bit constant multiplied by four; top four bits come from current PC. Uncommon.

Jump to register sends control to a 32-bit absolute address in a register:

jr $t3

Instructions must be four-byte aligned;

the contents of the register must be a multiple of 4.

Jump and Link

Jump and link stores a return address in $ra for implementing subroutines:

jal mysub

# Control resumes here after the jr

# ...

mysub:

# ...

jr $ra # Jump back to caller

jalr is similar; target address supplied in a register.

Branches

Used for conditionals or loops. E.g., “send control to myloopif the contents of $t0 is not equal to the contents of $t1.”

myloop:

# ...

bne $t0, $t1, myloop

# ...

beq is similar “branch if equal”

A “jump” supplies an absolute address; a “branch”

supplies an offset to the program counter.

On the MIPS, a 16-bit signed offset is multiplied by four and added to the address of the next instruction.

Branches

Another family of branches tests a single register:

bgez $t0, myelse # Branch if $t0 positive

# ...

myelse:

# ...

Others in this family:

blez Branch on less than or equal to zero bgtz Branch on greater than zero

bltz Branch on less than zero

bltzal Branch on less than zero and link

bgez Branch on greater than or equal to zero

bgezal Branch on greter than or equal to zero and link

“and link” variants also (always) put the address of the next instruction into $ra, just like jal.

Other Instructions

syscall causes a system call exception, which the OS catches, interprets, and usually returns from.

SPIM provides simple services: printing and reading integers, strings, and floating-point numbers, sbrk() (memory request), and exit().

# prints "the answer = 5"

.data str:

.asciiz "the answer = "

.text

li $v0, 4 # system call code for print_str la $a0, str # address of string to print syscall # print the string

li $v0, 1 # system call code for print_int li $a0, 5 # integer to print

syscall # print it

Other Instructions

Exception Instructions tge tlt ... Conditional traps

break Breakpoint trap, for debugging eret Return from exception

Multiprocessor Instructions

ll sc Load linked/store conditional for atomic operations sync Read/Write fence: wait for all memory loads/stores

Coprocessor 0 Instructions (System Mgmt) lwr lwl ... Cache control

tlbr tblwi ... TLB control (virtual memory)

... Many others (data movement, branches) Floating-point Coprocessor Instructions add.d sub.d ... Arithmetic and other functions

lwc1 swc1 ... Load/store to (32) floating-point registers bct1t ... Conditional branches

Instruction Encoding

Register-type: add, sub, xor, . . .

op:6 rs:5 rt:5 rd:5 shamt:5 funct:6

Immediate-type: addi, subi, beq, . . .

op:6 rs:5 rt:5 imm:16

Jump-type: j, jal . . .

op:6 addr:26

Register-type Encoding Example

op:6 rs:5 rt:5 rd:5 shamt:5 funct:6

add $t0, $s1, $s2

add encoding from the MIPS instruction set reference:

SPECIAL

000000 rs rt rd 0

00000

ADD 100000

Since $t0 is register 8; $s1 is 17; and $s2 is 18,

000000 10001 10010 01000 00000 100000

Register-type Shift Instructions

op:6 rs:5 rt:5 rd:5 shamt:5 funct:6

sra $t0, $s1, 5

sra encoding from the MIPS instruction set reference:

SPECIAL 000000

0

00000 rt rd sa SRA

000011

Since $t0 is register 8 and $s1 is 17,

000000 00000 10010 01000 00101 000011

Immediate-type Encoding Example

op:6 rs:5 rt:5 imm:16

addiu $t0, $s1, -42

addiu encoding from the MIPS instruction set reference:

ADDIU

001001 rs rt immediate

Since $t0 is register 8 and $s1 is 17,

001001 10001 01000 1111 1111 1101 0110

Jump-Type Encoding Example

op:6 addr:26

jal 0x5014

jal encoding from the MIPS instruction set reference:

JAL

000011 instr_index

Instruction index is a word address

000011 00 0000 0000 0001 0100 0000 0101

Assembler Pseudoinstructions

Branch always b label → beq $0, $0, label Branch if equal

zero

beqz s, label → beq s, $0, label

Branch greater or equal

bge s, t, label slt $1, s, t beq $1, $0, label Branch greater or

equal unsigned

bgeu s, t, labelsltu $1, s, t beq $1, $0, label Branch greater

than

bgt s, t, label slt $1, t, s bne $1, $0, label Branch greater

than unsigned

bgtu s, t, labelsltu $1, t, s bne $1, $0, label Branch less than blt s, t, label slt $1, s, t

bne $1, $0, label Branch less than

unsigned

bltu s, t, labelsltu $1, s, t bne $1, $0, label

Assembler Pseudoinstructions

Load immediate 0≤ j ≤ 65535

li d, j → ori d, $0, j Load immediate

−32768 ≤ j < 0

li d, j → addiu d, $0, j

Load immediate li d, j liu d, hi16(j) ori d, d, lo16(j)

Move move d, s → or d, s, $0

Multiply mul d, s, t mult s, t mflo d Negate unsigned negu d, s → subu d, $0, s Set if equal seq d, s, t xor d, s, t

sltiu d, d, 1 Set if greater or

equal

sge d, s, t slt d, s, t xori d, d, 1 Set if greater or

equal unsigned

sgeu d, s, tsltu d, s, t xori d, d, 1 Set if greater than sgt d, s, t → slt d, t, s

Expressions

Initial expression:

x + y + z * (w + 3)

Reordered to minimize intermediate results; fully parenthesized to make order of operation clear.

(((w + 3) * z) + y) + x addiu $t0, $a0, 3 # w: $a0 mul $t0, $t0, $a3 # x: $a1 addu $t0, $t0, $a2 # y: $a2 addu $t0, $t0, $a1 # z: $a3 Consider an alternative:

(x + y) + ((w + 3) * z) addu $t0, $a1, $a2

addiu $t1, $a0, 3 # Need a second temporary mul $t1, $t1, $a3

addu $t0, $t0, $t1

Conditionals

if ((x + y) < 3) x = x + 5;

else

y = y + 4;

addu $t0, $a0, $a1 # x + y slti $t0, $t0, 3 # (x+y)<3 beq $t0, $0, ELSE

addiu $a0, $a0, 5 # x += 5

b DONE

ELSE:

addiu $a1, $a1, 4 # y += 4 DONE:

Do-While Loops

Post-test loop: body always executes once a = 0;

b = 0;

do {

a = a + b;

b = b + 1;

} while (b != 10);

move $a0, $0 # a = 0 move $a1, $0 # b = 0

li $t0, 10 # load constant TOP:

addu $a0, $a0, $a1 # a = a + b addiu $a1, $a1, 1

# b = b + 1

bne $a1, $t0, TOP # b != 10?

While Loops

Pre-test loop: body may never execute

a = 0;

b = 0;

while (b != 10) { a = a + b;

b = b + 1;

}

move $a0, $0 # a = 0 move $a1, $0 # b = 0 li $t0, 10

b TEST # test first BODY:

addu $a0, $a0, $a1 # a = a + b addiu $a1, $a1, 1 # b = b + 1 TEST:

bne $a1, $t0, BODY # b != 10?

For Loops

“Syntactic sugar” for a while loop

for (a = b = 0 ; b != 10 ; b++) a += b;

is equivalent to a = b = 0;

while (b != 10) { a = a + b;

b = b + 1;

}

move $a1, $0 # b = 0 move $a0, $a1 # a = b li $t0, 10

b TEST # test first BODY:

addu $a0, $a0, $a1 # a = a + b addiu $a1, $a1, 1 # b = b + 1 TEST:

bne $a1, $t0, BODY # b != 10?

Arrays

int a[5];

void main() {

a[4] = a[3] = a[2] = a[1] = a[0] = 3;

a[1] = a[2] * 4;

a[3] = a[4] * 2;

}

.. . 0x10010010: a[4]

0x1001000C: a[3]

0x10010008: a[2]

0x10010004: a[1]

0x10010000: a[0]

.. .

.comm a, 20 # Allocate 20 .text # Program next main:

la $t0, a # Address of a li $t1, 3

sw $t1, 0($t0) # a[0]

sw $t1, 4($t0) # a[1]

sw $t1, 8($t0) # a[2]

sw $t1, 12($t0) # a[3]

sw $t1, 16($t0) # a[4]

lw $t1, 8($t0) # a[2]

sll $t1, $t1, 2 # * 4 sw $t1, 4($t0) # a[1]

lw $t1, 16($t0) # a[4]

sll $t1, $t1, 1 # * 2 sw $t1, 12($t0) # a[3]

jr $ra

Summing the contents of an array

int i, s, a[10];

for (s = i = 0 ; i < 10 ; i++) s = s + a[i];

move $a1, $0 # i = 0 move $a0, $a1 # s = 0 li $t0, 10

la $t1, a # base address of array

b TEST

BODY:

sll $t3, $a1, 2 # i * 4 addu $t3, $t1, $t3 # &a[i]

lw $t3, 0($t3) # fetch a[i]

addu $a0, $a0, $t3 # s += a[i]

addiu $a1, $a1, 1 TEST:

sltu $t2, $a1, $t0 # i < 10?

bne $t2, $0, BODY

Summing the contents of an array

int s, *i, a[10];

for (s=0, i = a+9 ; i >= a ; i--) s += *i;

move $a0, $0 # s = 0 la $t0, a # &a[0]

addiu $t1, $t0, 36 # i = a + 9

b TEST

BODY:

lw $t2, 0($t1) # *i addu $a0, $a0, $t2 # s += *i addiu $t1, $t1, -4 # i--TEST:

sltu $t2, $t1, $t0 # i < a beq $t2, $0, BODY

Strings: Hello World in SPIM

# For SPIM: "Enable Mapped I/O" must be set

# under Simulator/Settings/MIPS .data

hello:

.asciiz "Hello World!\n"

.text main:

la $t1, 0xffff0000 # I/O base address la $t0, hello

wait:

lw $t2, 8($t1) # Read Transmitter control andi $t2, $t2, 0x1 # Test ready bit

beq $t2, $0, wait

lbu $t2, 0($t0) # Read the byte

beq $t2, $0, done # Check for terminating 0 sw $t2, 12($t1) # Write transmit data addiu $t0, $t0, 1 # Advance to next character

b wait

done:

jr $ra

Hello World in SPIM: Memory contents

[00400024] 3c09ffff lui $9, -1

[00400028] 3c081001 lui $8, 4097 [hello]

[0040002c] 8d2a0008 lw $10, 8($9) [00400030] 314a0001 andi $10, $10, 1

[00400034] 1140fffe beq $10, $0, -8 [wait]

[00400038] 910a0000 lbu $10, 0($8)

[0040003c] 11400004 beq $10, $0, 16 [done]

[00400040] ad2a000c sw $10, 12($9) [00400044] 25080001 addiu $8, $8, 1 [00400048] 0401fff9 bgez $0 -28 [wait]

[0040004c] 03e00008 jr $31

[10010000] 6c6c6548 6f57206f H e l l o W o [10010008] 21646c72 0000000a r l d ! . . . .

相關文件