目录

1 指令格式

零地址、一地址、二地址、三地址指令的格式:

操作码地址码 1地址码 2地址码 3
OPA1A2A3

1.1 定长操作码

定长操作码指的是操作码的位数不变,n 位操作码的指令系统最大可以有 2n 条指令。

1.2 变长操作码

变长操作码指的是操作码的位数不固定,相应的地址码根据操作码长度的不同而发生变化。

假设指令字长为 16 位,有四种指令格式(零地址、一地址、二地址、三地址指令),操作码和地址码均占 4 位,则一种扩展操作码方案:

指令操作码地址码 1地址码 2地址码 3
15 条三地址指令0000A1A2A3
.0001A1A2A3
.............
.1110A1A2A3
15 条二地址指令11110000A2A3
.11110001A2A3
.............
.11111110A2A3
15 条一地址指令111111110000A3
.111111110001A3
.............
.111111111110A3
16 条零地址指令1111111111110000
.1111111111110001
.............
.1111111111111111

另一种扩展操作码方案:

指令操作码地址码 1地址码 2地址码 3
15 条三地址指令0000A1A2A3
.0001A1A2A3
.............
.1110A1A2A3
12 条二地址指令11110000A2A3
.11110001A2A3
.............
.11111011A2A3
63 条一地址指令111111000000A3
.111111000001A3
.............
.111111001111A3
.111111010000A3
.111111010001A3
.............
.111111111110A3
16 条零地址指令1111111111110000
.1111111111110001
.............
.1111111111111111

1.3 相关例题

【例 1】一个计算机系统采用 32 为指令字长,地址码为 12 位,若定义了 250 条二地址指令,则还可以定义多少条单地址指令?

【解】二地址指令的操作码占据 32-12-12=8 位,因此二地址指令最多可定义 28=256 条指令,但现在只定义了 250 条指令,剩余 6 位分配给一地址指令,可以有 6 * 212 条指令,即 24K 条指令。

【例 2】某计算机按字节编址,指令字长固定且只有两种指令格式,其中三地址指令 29 条,二地址指令 107 条,每个地址字段为 6 位,则指令字长至少为多少?

【解】由题目可得:指令字长固定且只有两种指令格式,分别为三地址指令和二地址指令。

三地址指令 29 条,24 < 29 < 25,因此三地址指令的操作码至少有 5 位。现假设三地址指令只有 5 位操作码,那么三地址指令最多可以有 25=32 条指令,现只有 29 条,说明剩余 3 位分配给了一地址指令。至此,三地址指令已占用 5+3 * 6=23 位。

二地址能实现的指令数为:3 * 26=192 > 107,显然是够用的,所以操作码 5 位完全够用。因此指令字长至少为 23 位,又因为按字节编址,所以指令字长至少为 24 位。

2 寻址方式

2.1 指令寻址

寻址方式执行细节备注
顺序寻址执行本条指令时:(PC)+1 -> PC;然后开始执行下一条指令“1” 表示一个指令字长(对于 CISC,指令字长是不固定的;对于 RISC,指令字长是固定的)
跳跃寻址(绝对跳转)执行本条指令时:(PC)+1 -> PC;执行本条指令后:add -> PC;然后开始执行目标指令add 为绝对地址,“1” 表示一个指令字长
跳跃寻址(相对跳转)执行本条指令时:(PC)+1 -> PC;执行本条指令后:(PC)+offset -> PC;然后开始执行目标指令offset 为相对偏移量,用补码表示;“1” 表示一个指令字长

【注 1】跳跃寻址(相对跳转)从执行本条指令时到执行本条指令后的 PC 总变化:(PC)+offset+1 -> PC。此处很容易犯错!!!
【注 2】有的题目,相对偏移量 offset 表示的是相对偏移指令数,而不是相对偏移地址!若题目已暗示了是相对偏移指令数,那么若指令字长为 16 位(按字节编址),则根据:(PC)+offset+1 -> PC,可得转移目标地址为(PC)+offset*2+2;若指令字长为 8 位(按字节编址),则根据:(PC)+offset+1 -> PC,可得转移目标地址为(PC)+offset*1+1
【注 3】计算跳跃寻址(相对跳转)的目标地址时,需要将偏移量从补码转化为原码再计算(因为内存地址是无符号数)。此处很容易犯错!!!我感觉相对寻址好像也有这个问题要注意

2.2 数据寻址

  • imm:立即数
  • add:内存地址
  • R:寄存器
  • PC:程序计数器(x86 称为 IP)
  • BR:基址寄存器,内容由操作系统决定
  • IX:变址寄存器,内容由用户(程序员)指定
  • SP:堆栈(指针)寄存器
  • 括号:表示内存地址内容,或寄存器内容

设有效地址为 8 位,寄存器、PC、存储器字长为 16 位,则有:

寻址方式有效地址 EA访存次数寻址范围访问地址
隐含寻址程序指定(一般为 R)0~~
立即寻址imm0~~
直接寻址add1280~28-1
一次间接寻址(add)22160~216-1
二次间接寻址((add))32160~216-1
寄存器寻址R02160~216-1
寄存器一次间接寻址(R)12160~216-1
寄存器二次间接寻址((R))22160~216-1
相对寻址(PC) + add128(PC)-(27)+1~(PC)+(27-1)+1
基址寻址(BR) + add128(BR)-(27)~(BR)+(27-1)
基址间接寻址((BR) + add)22160~216-1
变址寻址(IX) + add12160~216-1
变址间接寻址(变址间址)((IX) + add)22160~216-1
间接变址寻址(间址变址)(IX) + (add)22160~216-1
硬堆栈寻址(寄存器作堆栈)(SP) 和 R0~~
软堆栈寻址(内存作堆栈)(SP) 和 R1~~

【注】相对寻址中,add 为相对指令数。此处默认一个指令字长为 8 位,按字节编址,所以访问地址范围为(PC)-(27)+1~(PC)+(27-1)+1;若一个指令字长为 16 位,按字节编址,则应写成(PC)-(27)*2+2~(PC)+(27-1)*2+2

补充:堆栈寻址的执行细节

  • 堆栈顶在小地址方向
指令执行流
push(SP)-1 -> SP, (R) -> MSP
pop(MSP) -> R, (SP)+1 -> SP
  • 堆栈顶在大地址方向
指令执行流
push(SP)+1 -> SP, (R) -> MSP
pop(MSP) -> R, (SP)-1 -> SP

【注】堆栈指针始终指向栈顶元素!!!

补充:指令中的操作数地址

  • 大端方式:指令中给出的地址是操作数最高有效字节(MSB)的地址
  • 小端方式:指令中给出的地址是操作数最低有效字节(LSB)的地址

2.3 相关例题

【例 1】设相对寻址的转移指令占 3 个字节,第一字节为操作码,第二,三字节为相对位移量(补码表示)。而且数据在存储器中采用以低字节地址为字地址的存放方式。每当 CPU 从存储器取出一个字节时,即自动完成 (PC)+1PC。

(1)若 PC 当前值为 240(十进制),要求转移到 290(十进制),则转移指令的第二、三字节的机器代码是什么?

(2)若 PC 当前值为 240(十进制),要求转移到 200(十进制),则转移指令的第二、三字节的机器代码是什么?

【解】执行转移指令时,PC = 240+3 = 243,指令执行结束后:

(1)转移到 290,相对偏移量为 290-243=47,转成补码为 002FH。

(2)转移到 200,相对偏移量为 200-243=-43,转成补码为 FFD5H。

【例 2】某计算机采用大端方式,按字节编址。某指令中操作数的机器数为 1234 FF00H,该操作数采用基址寻址方式,形式地址(用补码表示)为 FF12H,基址寄存器的内容为 F000 0000H, 则该操作数的 LSB(最低有效字节)所在的地址是什么?

【解】因为 FF12H 为负数补码,所以需转化为原码 80EEH,然后用基址相减该值得到地址:F000 0000H - 80EEH = EFFF 7F12H。因为是大端存储,所以 LSB 所在地址为 EFFF 7F15H。

3 汇编指令

3.0 Intel 格式和 AT&T 格式

Intel 格式AT&T 格式
第一个:目的操作数;第二个:源操作数第一个:源操作数;第二个:目的操作数
byte ptr、word ptr、dword ptrb、w、l
[edx+eax*2+8]8(%edx, %eax, 2)

【注】在汇编指令中,word(字)均表示 16 位!

3.1 数据传送指令

  • mov 指令:不能从内存到内存!
  • push 指令
  • pop 指令

3.2 算术和逻辑指令

  • add 指令
  • sub 指令
  • inc 指令
  • dec 指令
  • imul 指令:带符号乘法,可以两个或三个操作数,运算结果可能溢出
  • idiv 指令:带符号除法,只有一个操作数,商送 eax,余数送 edx
  • and 指令
  • or 指令
  • not 指令:位翻转
  • xor 指令
  • neg 指令:取反
  • shl/shr 指令

3.3 控制流指令

  • jmp 指令
  • call/ret 指令
  • int/iret 指令
  • test/cmp 指令

【标志位】

  • ZF:零标志(无符号 / 带符号):计算结果为 0 时,ZF = 1
  • OF:溢出标志(带符号):OF = 最高位(即符号位)进/借位 ⊕ 次高位(即数值的最高位)进/借位
  • SF:符号标志(带符号):SF = 符号位
  • CF:进 / 借位(carry)标志(无符号):最高位向更高位进 / 借位时,CF = 1
  • 无符号数和带符号数:
条件指令含义标志位备注
je相等转移ZF=1a-b=0
jne不相等转移ZF=0a-b≠0
  • 无符号数:
条件指令含义标志位备注
ja大于转移CF=0 且 ZF=0a-b>0 且 a-b 没有借位
jb小于转移CF=1a-b<0,说明 a-b 不够减,一定借位
jae大于或等于转移CF=0 且 ZF=0a-b>=0 且 a-b 没有借位
jbe小于或等于转移CF=1 或 ZF=1a-b=0,或 a-b<0 有借位
  • 带符号数:
条件指令含义标志位备注
jg大于转移SF=OF 且 ZF=0SF=OF 时表示的是大于
jl小于转移SF≠OF 且 ZF=0SF≠OF 时表示的是小于
jge大于或等于转移SF=OFSF=OF 时表示的是大于
jle小于或等于转移SF≠OF 或 ZF=1SF≠OF 时表示的是小于

补充:使用 SF 和 OF 判断大小关系

cmp ah, bh为例,a-b 测试:

OFOF 说明SFSF 说明结果
0没有溢出,逻辑上真正结果的正负 = 实际结果的正负1实际结果为负逻辑上真正的结果为负,(ah)<(bh)
1有溢出,逻辑上真正结果的正负≠实际结果的正负1实际结果为负逻辑上真正的结果为非负,(ah)≥(bh)
1有溢出,逻辑上真正结果的正负≠实际结果的正负0实际结果为非负逻辑上真正的结果为负,(ah)<(bh)
0没有溢出,逻辑上真正结果的正负 = 实际结果的正负0实际结果为非负逻辑上真正的结果为非负,(ah)≥(bh)

3.4 相关例题

【例】某机器有一个标志寄存器,其中有进位 / 借位标志 CF、零标志 ZF、符号标志 SF 和溢出标志 OF,条件转移指令 bgt(无符号整数比较大于时转移)的转移条件是?

【解】判断无符号整数 A>B 成立,满足的条件是结果不等于 0,即零标志 ZF=0,并且两个数相减时, A>B 是不会造成借位的,即进位 / 借位标志 CF=0,写成逻辑表达式就是(CF+ZF)'=1