Digital-Design-and-Computer-Architecture-第六章归纳

0 前言

这一章主要学习MIPS架构,黑书的结构感觉有点混乱,所以按一定的逻辑重新组织了一下各个部分的内容。这一篇笔记类似于“字典”的形式,方便复习或查阅。

1 Four Principles in MIPS Design

  1. Simplicity favors regularity.
  2. Make the common case fast.
  3. Smaller is faster.
  4. Good design demands good compromises.

2 Three Operands

Register Set/Register File

Name Number(5 bits) Use
$0 0 the constant value 0
$at 1 assembler temporary
$v0-$v1 2-3 function return value
$a0-$a3 4-7 function arguments
$t0-$t7 8-15 temporary variables
$s0-$s7 16-23 saved variables
$t8-$t9 24-25 temporary variables
$k0-$k1 26-27 operating system (OS) temporaries
$gp 28 global pointer
$sp 29 stack pointer
$fp 30 frame pointer
$ra 31 function return address

Memory

Organization Pattern

  • MIPS uses a byte-addressable memory.

  • Big-Endian and Little-Endian:

    endian

Memory Map

memory_map

Constants/Immediates

The immediate specified in an instruction is a 16-bit two’s complement number in the range [–32,768, 32,767].

3 Instructions Set

R-Type

Instruction Format

R_type

I-Type

Instruction Format

I_type

J-Type

Instruction Format

J_Type

F-Type

Instruction Format

F_Type

Addressing Modes

  • Register-Only Addressing

    Register-only addressing uses registers for all source and destination operands. All R-type instructions use register-only addressing.

  • Immediate Addressing

    Immediate addressing uses the 16-bit immediate along with registers as operands. Some I-type instructions, such as add immediate (addi) and load upper immediate (lui), use immediate addressing.

  • Base Addressing

    Memory access instructions, such as load word (lw) and store word (sw), use base addressing. The effective address of the memory operand is found by adding the base address in register rs to the sign-extended 16-bit offset found in the immediate field.

  • PC-Relative Addressing

    Conditional branch instructions use PC-relative addressing to specify the new value of the PC if the branch is taken. The 16-bit immediate field gives the number of instructions between the BTA and the instruction after the branch instruction.

  • Pseudo-Direct Addressing

    The J-type instruction encoding does not have enough bits to specify a full 32-bit JTA. Fortunately, the two least significant bits, $JTA_{1:0}$, should always be 0, because instructions are word aligned. The next 26 bits, $JTA_{27:2}$, are taken from the addr field of the instruction. The four most significant bits, $JTA_{31:28}$, are obtained from the four most significant bits of PC + 4. This addressing mode is called pseudo-direct.

    Because the four most significant bits of the JTA are taken from PC + 4,
    the jump range is limited.

MIPS Instructions Tables

table1

table2

4 Programming

32-Bit Constant

  • The and instruction is useful for masking bits.

  • The or instruction is useful for combining bits from two registers.

  • A NOR $0 = NOT A.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    # 32-BIT CONSTANT

    # High-Level Code
    int a = 0x6d5e4f3c;

    #MIPS Assembly Code
    # $s0=a
    lui $s0, 0x6d5e
    ori $s0, $s0, 0x4f3c

Conditional Statements

if Statement

1
2
3
4
5
6
7
8
9
10
# High-Level Language
if (i==j)
f=g+h;
f=f-i;
#MIPS Assemble Language
# $s0=f, $s1=g, $s2=h, $s3=i, s4=j
bne $s3, $s4, target # if $s3 != $s4 then target
add $s1, $s2, $s3 # $s1 = $s2 + $s3
target:
sub $s1, $s1, $s3 # $s1 = $s1 - $s3

if/else Statement

1
2
3
4
5
6
7
8
9
10
11
12
13
# High-Level Language
if (i==j)
f=g+h;
else
f=f-i;
#MIPS Assemble Language
# $s0=f, $s1=g, $s2=h, $s3=i, s4=j
bne $s3, $s4, else # if $s3 != $s4 then else
add $s1, $s2, $s3 # $s1 = $s2 + $s3
j target # jump to target
else:
sub $s1, $s1, $s3 # $s1 = $s1 - $s3
target:

switch/case Statement

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# Hight-Level Language
swtich (amount){
case 20: fee=2; break;
case 50: fee=3; break;
case 100: fee=5; break;
default: fee=0;
}
#MIPS Assemble Language
# $s0=fee, $s1=amount
case20:
add $t0, $0, 20 # $t0 = $0 + 20
bne $t0, $s1, case50 # if $t0 != $s1 then case50
addi $s0, $0, 2 # $s0 = $0 + 2
j done # jump to done
case50:
add $t0, $0, 50
bne $t0, $s1, case100
addi $s0, $0, 3
j done
case100:
add $t0, $0, 100
bne $t0, $s1, default
addi $s0, $0, 5
j done
default:
addi $s0, $0, 0
done:

Loop Statement

while Loop

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# High-Level Language
int pow=1;
int x=0;
while(pow!=128){
pow=pow*2;
x=x+1;
}
# MIPS Assemble Language
# $s0=pow, $s1=x
addi $s0, $0, 1 # $s0 = $0 + 1
addi $s1, $0, 0 # $s1 = $0 + 0

addi $t0, $0, 128 # $t0 = $0 + 128
while:
beq $s0, $t0, target # if $s0 == $t0 then target
sll $s0, $s0, 1 # $s0 = $s0 << 1
addi $s1, $0, 1 # $s1 = $0 + 1
j while # jump to while
target:

for Loop

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# for Loop
# High-Level Language
int sum=0;
for (i=0:i!=10:i=i+1){
sum=sum+i;
}
# MIPS Assemble Language
# $s0=sum, $s1=i
addi $s0, $0, 0 # $s0 = $0 + 0
addi $s1, $0, 0 # $s1 = $0 + 0

addi $t0, $0, 10 # $t0 = $0 + 10
for:
beq $s1, $t0, target # if $s1 == $t0 then target
add $s0, $s0, $s1 # $s0 = $s0 + $t0
addi $s1, $s1, 1 # $s1 = $s1 + 1
j for # jump to for
target:
# Using slt Ver.
addi $s0, $0, 0 # $s0 = $0 + 0
addi $s1, $0, 0 # $s1 = $0 + 0

addi $t0, $0, 11 # $t0 = $0 + 10
for:
slt $t1, $s1, $t0 # $t1 = ($s1 < $t0) ? 1 : 0
beq $t1, $0, target # if $t1 == $0 then target
add $s0, $s0, $s1 # $s0 = $s0 + $s1
addi $s1, $s1, 1 # $s1 = $s1 + 1
j for # jump to for
target:

Function

Example 1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# High-Level Language
int main(){
int y;
y=diffofsums(2,3,4,5);
}
int diffofsums(int f,int g,int h,int i){
int result;
result=(f+g)-(h+i);
return result;
}
# MIPS Assemble Language
# $s0=y
main:
addi $a0, $0, 2 # $a0 = $0 + 2
addi $a1, $0, 3 # $a1 = $0 + 3
addi $a2, $0, 4 # $a2 = $0 + 4
addi $a3, $0, 5 # $a3 = $0 + 5
jal diffofsums # jump to diffofsums and save position to $ra
add $s0, $v0, $0 # $s0 = $v0 + $0
...
# $s0=result
diffofsums:
addi $sp, $sp, -4 # $sp = $sp + -4
sw $s0, 0($sp)
add $t0, $a0, $a1 # $t0 = $t0 + $t1
add $t1, $a2, $a3 # $t1 = $a2 + $a3
sub $s0, $t0, $t1 # $s0 = $t0 - $t1
add $v0, $0, $s0 # $v0 = $0 + $s0
lw $s0, 0($sp)
addi $sp, $sp, 4 # $sp = $sp + 4
jr $ra # jump to $ra

Example 2 (Recursive Function)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# High-Level Language
int factorial(int n){
if(n<=1)
return 1;
else
return (n*factorial(n-1));
}
# MIPS Assemble Language
factorial:
addi $sp, $sp, -8 # $sp = $sp + -8
sw $a0, 4($sp)
sw $ra, 0($sp)
addi $t0, $0, 2 # $t0 = $0 + 2
slt $t0, $a0, $t0 # $t0 = ($a0 < $t0) ? 1 : 0
beq $t0, $0, else # if $t0 == $0 then else
addi $v0, $0, 1 # $v0 = $0 + 1
addi $sp, $sp, 8 # $sp = $sp + 8
jr $ra # jump to $ra
else:
addi $a0, $0, -1 # $a0 = $0 + -1
jal factorial # jump to factorial and save position to $ra
lw $ra, 0($sp)
lw $a0, 4($sp)
addi $sp, $sp, 8 # $sp = $sp + 8
mul $v0, $v0, $a0
jr $ra # jump to $ra

factorial

5 Compiling, Assembling, and Loading

diagram

  1. Compilation: A compiler translates high-level code into assembly language.

  2. Assembling: The assembler turns the assembly language code into an object file containing machine language code.

    On the first pass, the assembler assigns instruction addresses and finds all the symbols, such as labels and global variable names. The names and addresses of the symbols are kept in a symbol table.

    On the second pass through the code, the assembler produces the machine language code. Addresses for the global variables and labels are taken from the symbol table. The machine language code and symbol table are stored in the object file.

  3. Linking: The job of the linker is to combine all of the object files into one machine language file called the executable.

    exe

  4. Loading: The operating system loads a program by reading the text segment of the executable file from a storage device (usually the hard disk) into the text segment of memory. The operating system sets $gp to 0x10008000 (the middle of the global data segment) and $sp to 0x7FFFFFFC (the top of the dynamic data segment), then performs a jal 0x00400000 to jump to the beginning of the program.

作者

Doxel

发布于

2022-09-05

更新于

2022-09-06

许可协议

评论