扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
chapter 6 Architecture
MIPS Instruction Set — ECS Networking (pacific.edu)
6.1 IntroductionFour design principles:
simplicity favors regularity
make the common case fast
smaller is faster
good design demands good compromises
MIPS Architecture - Microprocessor without interlocked piped stages architecture 简单易学,但不太实用
6.2.1 Instructions指令add a, b, c
add
mnemonic助记符
a
destination operand目标操作数
b,c
source operands操作数
简单设计:simplicity favors regularity
多条指令
a = b + c - d
→add t, b, c sub a, t, d
加速常见情况:make the common case fast
编码长度:
RISC(Reduced instruction set computer)
精简指令集,拥有少量简单的指令
CISC(Complex instruction set computers)
复杂指令集
6.2.2 Operands操作数:Registers, Memory, and Constants操作数的来源:寄存器/内存
寄存器
MIPS32有32个32位寄存器;比存储器快1000倍
越小越快:Smaller is faster
$0 always contains the value 0 because this constant is so frequently used in computer programs.
保存寄存器
临时变量寄存器
常数-立即数 存储在指令里
存储器-大但是慢
RISC的指令,只能作用在常数/寄存器上;MISC还能直接作用到寄存器中
字寻址存储器:每32位数据字对应一个唯一的32位地址
MIPS实际使用的是字节寻址
6.3 Machine Language机器语言三种汇编指令
6.3.1 R-Type Instructions 寄存器类型 6.3.2 I-Type Instructions 立即数类型 6.3.3 J-Type Instructions 跳转类型地址不是32位的吗?j类型里addr是26位的??
机器→汇编
6.3.5 The Power of the Stored Program 存储程序 - 通用计算能力 6.4 Programming编程 6.4.1 Arithmetic/Logical Instructions 算数/逻辑指令1 逻辑按位操作:
and: 用于掩码操作(Masking)
or: 用于组合操作(Combining)
nor: 或非,用于反相操作(Inverting)
2 移位指令
3对立即数操作:
间接加载高位立即数: lui
32-bit constants using load upper immediate (lui) and ori:
4伪指令
nop: 不对处理器执行产生影响,仅占用一条指令的时间空间,仅将PC推进到下一条指令
mv: 在寄存器之间传递数据 mv $s0 $s7 → or $s0 $0 $s7
li: 加载立即数到目标寄存器:先判断位数,在决定多条执行指令
5 乘除法:用lo, hi存储结果
32*32乘法,得64位结果
mult $s0, $s1
结果保存在{hi, lo}
32位除法,得32位商与余数
div $s0, $s1
商保存在lo, 余数保存在hi
从lo/hi读数
分支发生:taken;不发生 not taken
Types of branches:
1 Conditional条件分支
branch if equal (beq)beq $s0, $s1, target
branch if not equal (bne)
2 Unconditional无条件分支 → 跳转指令jump
jump (j) 跳转
jump register (jr) 跳转寄存器
jump and link (jal) 跳转和链接
# MIPS assembly
addi $s0, $0, 4 # $s0 = 0 + 4 = 4
addi $s1, $0, 1 # $s1 = 0 + 1 = 1
sll $s1, $s1, 2 # $s1 = 1<< 2 = 4
beq $s0, $s1, target # branch is taken
addi $s1, $s1, 1 # not executed
sub $s1, $s1, $s0 # not executed
target: # label
add $s1, $s1, $s0 # $s1 = 4 + 4 = 8
6.4.3 Conditional Statements 条件1 if
2 if/else
3 switch/case
6.4.4 Getting Loopy 循环1 while
2 for
3 量值比较
6.4.5 Arrays 数组1
搞清楚访问数据的大小
char (2bytes)或 longlong (8bytes)
操作字节:
100000 (32) lb rt, imm(rs) load byte [rt] = SignExt ([Address]7:0)
6.4.6 Function Calls 函数调用约定:
调用函数caller
将参数传递给被调用者:存在$a0 ~ $a3
中
跳转到被调用者
jal
被调用函数callee
执行函数
返回(结果)到调用者:存在$v0 ~ $v1
中
返回到调用点
不能破坏调用者的寄存器或内存
jr
jal
指令:
将下一条指令的地址存储到返回地址寄存器$ra中(存下被调用函数要返回到的调用点)
跳转到目标指令
001001 (9) | jal label | jump and link 跳转并链接 | $ra = PC + 4, PC = JTA |
---|
jr
指令:
把rs的内容返回PC,即PC跳到rs存的地址
001000 (8) | jr rs | jump register 跳转到存在rs地址 | PC = [rs] |
---|
int main(){simple();
...
}
void simple() return;
MIPS assembly code
0x00400200 main: jal simple #调用函数
0x00400204 ...
...
0x00401020 simple: jr $ra #返回
3 栈但是破坏了调用函数的寄存器,因而要把寄存器原来的值存到内存中,当被调用函数返回后,才能够内存中恢复原来寄存器的值。可以使用后进先出(LIFO)的“栈”数据结构存储临时变量。
栈的扩展与缩小:栈指针$sp
开始于高内存地址,通过地址递减来扩展栈空间
在函数修改寄存器前,将寄存器保存在栈中,返回前从栈中恢复这些寄存器。
创建栈空间
存储寄存器
使用寄存器执行函数
从栈中恢复寄存器原始值
回收栈空间
栈帧stack frame:函数为自己分配的栈空间
# $s0 = result, $sp为栈顶
diffofsums:
//栈指针减少 3*4 位,用于存储
addi $sp, $sp, -12 # make space on stack
# to store 3 registers
//保存现场
sw $s0, 8($sp) # save $s0 on stack
sw $t0, 4($sp) # save $t0 on stack
sw $t1, 0($sp) # save $t1 on stack
add $t0, $a0, $a1 # $t0 = f + g
add $t1, $a2, $a3 # $t1 = h + i
sub $s0, $t0, $t1 # result = (f + g) - (h + i)
add $v0, $s0, $0 # put return value in $v0
//恢复现场
lw $t1, 0($sp) # restore $t1 from stack
lw $t0, 4($sp) # restore $t0 from stack
lw $s0, 8($sp) # restore $s0 from stack
//恢复栈,栈平衡
addi $sp, $sp, 12 # deallocate stack space
//清除痕迹!->计算机安全
jr $ra # return to caller
下图展示了上述汇编代码执行时栈变化的示意图
4 受/不受保护的寄存器受保护寄存器(preserved):要么被调用函数不修改,若修改,则由被调用函数维护/ 保存(save)$s0 ~ $s7
存有(调用函数的)局部变量,因此必须被调用函数保存$ra
存有被调用函数要返回的地址,不能修改$sp
栈指针,由被调用函数扩展与收缩,被调用函数保存
在$sp
之上的栈空间:其他函数的栈帧,不能修改
不受保护寄存器(nonpreserved):由调用函数维护/ 保存(save),可由被调用函数任意修改$t0 ~ $t9
存放(调用函数的)临时变量,可由被调用函数任意修改,由调用函数保存$a0 ~ $a3
一般存调用函数要传给被调用函数的参数,一般会由被调用函数修改,由调用函数保存$v0 ~ $v1
存有被调用函数的返回值,会由callee修改,由调用函数保存
在$sp
之下的栈空间:callee自己分配的空间,有自己修改,由调用函数保存
被调用函数必须保存恢复任何要使用的受保护寄存器,可以随意改变不受保护寄存器。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xcsFeIDo-1669634365736)(image/image_aG9a8E36K4.png)]
5 递归函数调用High-level code
int factorial(int n) {if (n<= 1)
return 1;
else
return (n * factorial(n-1));
}
MIPS assembly code
// $a0
0x90 factorial: addi $sp, $sp, -8 # make room on stack
0x94 sw $a0, 4($sp) # store $a0
0x98 sw $ra, 0($sp) # store $ra
0x9C addi $t0, $0, 2 # $t0 = 2
0xA0 slt $t0, $a0, $t0 # n<= 1 ?
0xA4 beq $t0, $0, else # no: go to else
0xA8 addi $v0, $0, 1 # yes: return 1
0xAC addi $sp, $sp, 8 # restore $sp
0xB0 jr $ra # return
0xB4 else: addi $a0, $a0, -1 # n = n - 1
0xB8 jal factorial # recursive call
0xBC lw $ra, 0($sp) # restore $ra
0xC0 lw $a0, 4($sp) # restore $a0
0xC4 addi $sp, $sp, 8 # restore $sp
0xC8 mul $v0, $a0, $v0 # n * factorial(n-1)
0xCC jr $ra # return
对齐:MIPS不支持跨边界访问lw
对齐4字节边界
lb
不需要对齐,因为本身就以字节为单位
lh
对齐2字节边界
The first three modes (register-only, immediate, and base addressing) define modes of reading and writing operands. The last two (PC-relative and pseudo-direct addressing) define modes of writing the program counter, PC.
1 Register-Only Addressing 寄存器寻址Register-only addressing uses registers for all source and destination operands. All R-type instructions use register-only addressing.
2 Immediate Addressing 立即数寻址Immediate addressing uses the 16-bit immediate along with registers asoperands. Some** I-type instructions**, such as add immediate (addi) and load upper immediate (lui), use immediate addressing.
16位有符号数:$ -2^{15} $~ 2 15 − 1 2^{15}-1 215−1
对于大立即数:用伪汇编指令
逻辑运算-零扩展
算数运算-符号扩展
3 Base Addressing 基地址寻址Memory access instructions, such as load word (lw) and store word (sw),use base addressing. The effective address of the memory operand isfound by adding the base address in register rs to the sign-extended16-bit offset found in the immediate field.
基址+符号扩展的立即数
lw $s4, 72($s0)
地址 = $0 + 72
超大数组寻址:分步处理
4 PC-Relative Addressing PC相对地址Conditional branch instructions use PC-relative addressing to specify the new value of the PC if the branch is taken. The signed offset in the immediate field is added to the PC to obtain the new PC; hence, the branch destination address is said to be relative to the current PC.
0x10 beq $t0, $0, else
0x14 addi $v0, $0, 1
0x18 addi $sp, $sp, i
0x1C jr $ra
0x20 else: addi $a0, $a0, -1
0x24 jal factorial
若要条很远很远的地方:中间设置跳板
5 Pseudo-Direct Addressing 伪直接寻址 6.6 Compiling, Assembling, and Loading编译、汇编、加载
6.6.1 The Memory Map 内存映射转换成二进制代码(可执行文件) 开始执行程序
1 Compilation编译 2 Assembling汇编3 Linking链接4 Loading装入你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流