CISC(Complex Instruction Set Computing)
RISC(Reduced Instruction Set Computing)
MIPS是RISC的典型代表
RISC基本策略:
主流ISA:
寄存器:
MIPS内的寄存器:
MIPS指令的一般性语法格式: op dst, src1, src2
op:指令的基本功能
dst:保存结果的寄存器
src1:第一个操作数; src2:第二个操作数
加法操作:add dst, src1, src2
减法操作:sub dst, src1, src2
每条指令只有一种操作,每行一个指令
注释语句以“#”开始
0号寄存器($0 / $zero):0的专属寄存器,其值恒为零
立即数:指令中出现的常量数值
含有立即数的指令:op dst, src, imm
op+i表示对立即数的操作(eg:addi $s1, $s2, 5)
由于MIPS只能对寄存器与立即数进行运算,因此必须有特定的数据传输指令实现主存单元与寄存器的数据交换
LOAD类:主存单元→寄存器
STORE类:寄存器→主存单元
数据传输的语法格式:op reg, off(base)
reg:操作的寄存器
base:存储基址的寄存器(因为是地址,base的值为无符号数)
off:偏移量(单位为字节,可正可负)—— 偏移量必须为4的倍数
读写的存储单元实际地址为:base+off
加载字:lw reg, off(base)
存储字:sw reg, off(base)
加载字节:lb reg, off(base) lbu为无符号扩展
存储字节:sb reg, off(base)
注意:读入字节最高位视为符号位,向高24位扩展
加载半字:lh reg, off(base) lhu为无符号扩展
存储半字:sh reg, off(base)
如果变量比寄存器多,则把常用的变量保存在寄存器中,其他不常用的保存在存储器中
大印第安:最高有效字节在字内的最低地址
小印第安:最高有效字节在字内的最高地址
MIPS没有语句块的概念(不同于C语言的if-else、while等)
每条指令都对应一个word地址,使用标号标记其后的指令的地址 → **“标号名” + ‘:’ **
通过跳转机制调到标号处,实现转移
相等时转移(Branch If Equal):beq reg1, reg2, label
不等时转移(Branch If Not Equal):bne reg1, reg2, label
无条件转移(Jump):j label
C语言中for、while、do-while都可以改为MIPS
乘除法指令结算结果不是直接写入32个通用寄存器中,而是保存在两个特殊寄存器HI与LO
2条专用指令读写HI/LO:
move from high:mfhi dst
move from low:mflo dst
乘法操作:mult src1, src2
LO保存结果的低32位,HI保存结果的高32位
除法操作:div src1, src2
LO保存商,HI保存余数
当计算结果的位数超出计算机硬件的实际可存储位数时,即为溢出
MIPS会检测溢出(溢出时产生错误),但是有unsigned关键字的算术指令忽略溢出
overflow detection | no overflow detection |
---|---|
add dst, src1, src2 | addu dst, src1, src2 |
addi dst, src1, src2 | addiu dst, src1, src2 |
sub dst, src1, src2 | subu dst, src1, src2 |
instruction | C | MIPS |
---|---|---|
and | a=b&c | and $s1, $s2, $s3 |
and immediate | a=b&0x1 | andi $s1, $s2, $s3 |
or | a=b|c | or $s1, $s2, $s3 |
or immediate | a=b|0x5 | ori $s1, $s2, $s3 |
not or | a=~(b|c) | nor $s1, $s2, $s3 |
exclusive or | a=b^c | xor $s1, $s2, $s3 |
exclusive or immediate | a=b^0xF | xori $s1, $s2, $s3 |
移位的不同种类:
方向:左移&右移
性质:逻辑移位&算术移位
左移位低位补零;右移位:逻辑移位补0,算术移位补符号位
移位量:对于32位寄存器,移动位数合理最大取值为31,即0x1F
表示方式:5位的立即数&某寄存器的值(低5位有意义)
指令 | 功能 | 示例 |
---|---|---|
sll | 逻辑左移 | sll $dst, $src, imm/$x |
srl | 逻辑右移 | srl $dst, $src, imm/$x |
sra | 算数右移 | sra $dst, $src, imm/$x |
sllv | 逻辑可变左移 | sllv $dst, $src, imm/$x |
srlv | 逻辑可变右移 | srlv $dst, $src, imm/$x |
srav | 算数可变右移 | srav $dst, $src, imm/$x |
slt dst, src1, src2: Set on Less Than(如果src1 slt与bne、beq和$0组合可以实现所有的比较方式 slt的三种情况: MIPS定义了一组伪指令,从而使得程序更可读更易编写 注意:伪指令知识增加了可读性,最终要转换为实际指令 出现的问题:将一条伪指令转换成真实指令时,可能需要多条真实指令,指令之间必须通过寄存器传递信息,若果任意 使用寄存器,则寄存器的内容可能被误写 解决方案:保留**$1 ($at)**作为汇编器的专用寄存器 TAL(True Assembly Language):真实指令,计算机能理解和执行 MAL(MIPS Assembly Language):提供给汇编程序员使用的指令(含伪指令) 实现函数的六个步骤: 寄存器分配: 函数调用指令: PC(Program Counter)是一个特殊寄存器,用于保存当前正在执行的指令的地址(对程序员不可见,但是可以通过jal访问) 注:$ra中保存的地址为PC+4而不是PC,否则从函数返回时再次返回jal 保存和恢复寄存器: $sp:栈指针寄存器,指针指向栈底 栈帧:函数为获得保存寄存器而将$sp向0方向调整的空间(栈帧容量=要保存的寄存器数量×4) eg: addi $sp, $sp, -8 注意:栈增长方向为向0增长,堆增长方向为背0增长 局部变量和数组: 寄存器的保护分析 $s0~$s7:程序员变量 $ra:函数返回地址 $t0~$t9:临时变量(前提:MIPS约定其服务于表达式计算) 无需保护的情况:表达式中不调用子函数,故不存在被子函数修改的可能 需要保护的情况:表达式中调用子函数,故存在被子函数修改的可能 保护前提:如果其值在子函数调用前后必须保持一致 保护动作:调用子函数前保存,调用子函数后恢复 $a0~$a3, $v0~$v1:参数,返回值 $a0~$a3:传递给了子函数,故子函数可自由使用 $v0~$v1:因为子函数会设置返回值,故子函数可自由使用 保护前提:如果其值在子函数调用前后必须保持一致 保护动作:调用子函数前保存,调用子函数后恢复 $at:汇编器使用,无需保护 $sp:栈切换(通常属于操作系统范畴)时才需要保护 $fp、$gp:生成复杂存储布局时使用(属于便于范畴) 小结: Preserved Register:保护寄存器($s0~$s7、$ra) Non-preserved Register:非保护寄存器($t0~$t9、$a0~$a3、$v0~$v1) 存储型程序: 二进制兼容: 把指令当做数看待: MIPS的3类指令格式: I型指令:指令中包含立即数 lw / sw 的偏移是立即数;beq/bne同样包含有偏移 srl等移位指令也有4位立即数(移位位数),但不属于I型指令 J型指令:j和jal(jr不是J型指令) R型指令:所有其他指令 指令中包含6个域: 每个域都被视为无符号整数: NOP(0x00000000):即”sll $0, $0, 0“,主要用于解决流水线冲突 指令包括6个域: 具体含义: 注意: 如何计算32位立即数:(addi/ slti/ andi/ ori/……) 通过增加lui,MIPS可以用16位立即数处理任意大小的数据 B类指令:分支指令(beq与bne),主要用于构造if-else、while、for,同样具有:opcode,rs,rt,immediate结构。比较rs和rt,根据比较结果决定能够是否转移。 注意:并非所有的B类指令的rt域都是寄存器,需要指定要转移的地址。转移的范围通常很小(<50指令),函数调用和无条件跳转用J型指令 用immediate表示地址: PC相对寻址:PC为基地址,immediate为偏移(二进制补码) 下一条指令的PC值计算方法: immediate为16位符号数,范围为±215,意味着转移的指令数最大为215条。按照1行C代码对应10条指令,则可转移约3000行C代码 J型指令只定义了2个域: 要点: PC的高4位来自当前指令的高4位,J型指令的转移范围是256MB(只有jr指令可以跳转到4GB内任意地址) 每条指令的汇编基本步骤: 反汇编是汇编的逆过程,即将指令二进制代码转换为汇编代码 反汇编基本步骤:
位扩展
溢出检测
符号数
Signed
lb:扩展
add, addi, sub, mult, div: 检测
slt, slti: 符号数
Unsigned
lbu:无扩展
addu, addiu, subu, multu, divu: 不检测
sltu, sltiu:无符号数
伪指令
实现函数
函数调用约定
序号
名称
MIPS汇编约定的用途
分类
保护的前提条件
何时保护与恢复
16~23
$s0~$s7
程序员变量
强保护
如果需要使用
进入函数时保存,退出函数前恢复
31
$ra
函数返回地址
强保护
如果调用子函数
进入函数时保存,退出函数前恢复
————
————
——————
————
——————
————————————
2~3
$v0~$v1
函数返回值
弱保护
如果要求其值在子函数调用前后必须保持一致
调用子函数前保存,调用子函数后恢复
4~7
$a0~$a3
函数参数
弱保护
如果要求其值在子函数调用前后必须保持一致
调用子函数前保存,调用子函数后恢复
8~15,24~25
$t0~$t9
临时变量
弱保护
如果要求其值在子函数调用前后必须保持一致
调用子函数前保存,调用子函数后恢复
存储型程序概念
R型指令
opcode
rs
rt
rd
shamt
funct
316
5
5
5
5
60
域
含义
说明
opcode(6)
指令操作
R型指令的opcode固定为0b000000
funct(6)
与opcode组合,精确定义指令的具体操作
主要服务于R型指令(由于opcode为0,因此根据6位funct,R型指令最多有64个)
rs(5)
指定1st操作数(source寄存器)
rt(5)
指定2nd操作数(target寄存器)
rd(5)
指定结果回写的寄存器(destination寄存器)
eg: add rd, rs, rt
shamt(5)
移位指令中的移位位数
移位位数大于31没有意义;除了移位指令,该域恒为0
I型指令
opcode
rs
rt
immediate
316
5
5
160
域
含义
说明
opcode(6)
指令操作
I型指令的opcode为非零编码,可有264条指令
rs(5)
指定1st操作数(source寄存器)
rt(5)
指定2nd操作数(target寄存器)
immediate(16)
无符号或有符号数
1. 无符号数:位运算指令(and/or/nor……)、小于置位指令(slti……) 2. 有符号:分支指令(beq/bne……)、访存指令(lw/sw……)
B类指令
J型指令
opcode(31~26)
instr_index(25~0)
6
26
汇编实战
反汇编实战