G
N
I
D
A
O
L

【组成原理-指令】指令系统

1 指令格式

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

操作码 地址码1 地址码2 地址码3
OP A1 A2 A3

1.1 定长操作码

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

1.2 变长操作码

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

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

指令 操作码 地址码1 地址码2 地址码3
15 条三地址指令 0000 A1 A2 A3
. 0001 A1 A2 A3
. ... ... ... ...
. 1110 A1 A2 A3
15 条二地址指令 1111 0000 A2 A3
. 1111 0001 A2 A3
. ... ... ... ...
. 1111 1110 A2 A3
15 条一地址指令 1111 1111 0000 A3
. 1111 1111 0001 A3
. ... ... ... ...
. 1111 1111 1110 A3
16 条零地址指令 1111 1111 1111 0000
. 1111 1111 1111 0001
. ... ... ... ...
. 1111 1111 1111 1111

另一种扩展操作码方案:

指令 操作码 地址码1 地址码2 地址码3
15 条三地址指令 0000 A1 A2 A3
. 0001 A1 A2 A3
. ... ... ... ...
. 1110 A1 A2 A3
12 条二地址指令 1111 0000 A2 A3
. 1111 0001 A2 A3
. ... ... ... ...
. 1111 1011 A2 A3
63 条一地址指令 1111 1100 0000 A3
. 1111 1100 0001 A3
. ... ... ... ...
. 1111 1100 1111 A3
. 1111 1101 0000 A3
. 1111 1101 0001 A3
. ... ... ... ...
. 1111 1111 1110 A3
16 条零地址指令 1111 1111 1111 0000
. 1111 1111 1111 0001
. ... ... ... ...
. 1111 1111 1111 1111

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 ~ ~
立即寻址 imm 0 ~ ~
直接寻址 add 1 28 0~28-1
一次间接寻址 (add) 2 216 0~216-1
二次间接寻址 ((add)) 3 216 0~216-1
寄存器寻址 R 0 216 0~216-1
寄存器一次间接寻址 (R) 1 216 0~216-1
寄存器二次间接寻址 ((R)) 2 216 0~216-1
相对寻址 (PC) + add 1 28 (PC)-(27)+1~(PC)+(27-1)+1
基址寻址 (BR) + add 1 28 (BR)-(27)~(BR)+(27-1)
基址间接寻址 ((BR) + add) 2 216 0~216-1
变址寻址 (IX) + add 1 216 0~216-1
变址间接寻址(变址间址) ((IX) + add) 2 216 0~216-1
间接变址寻址(间址变址) (IX) + (add) 2 216 0~216-1
硬堆栈寻址(寄存器作堆栈) (SP) 和 R 0 ~ ~
软堆栈寻址(内存作堆栈) (SP) 和 R 1 ~ ~

【注】相对寻址中,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)+1->PC。

(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 ptr b、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=1 a-b=0
jne 不相等转移 ZF=0 a-b≠0
  • 无符号数:
条件指令 含义 标志位 备注
ja 大于转移 CF=0 且 ZF=0 a-b>0 且 a-b 没有借位
jb 小于转移 CF=1 a-b<0,说明 a-b 不够减,一定借位
jae 大于或等于转移 CF=0 且 ZF=0 a-b>=0 且 a-b 没有借位
jbe 小于或等于转移 CF=1 或 ZF=1 a-b=0,或 a-b<0 有借位
  • 带符号数:
条件指令 含义 标志位 备注
jg 大于转移 SF=OF 且 ZF=0 SF=OF 时表示的是大于
jl 小于转移 SF≠OF 且 ZF=0 SF≠OF 时表示的是小于
jge 大于或等于转移 SF=OF SF=OF 时表示的是大于
jle 小于或等于转移 SF≠OF 或 ZF=1 SF≠OF 时表示的是小于

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

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

OF OF 说明 SF SF 说明 结果
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

posted @ 2022-08-31 17:00  漫舞八月(Mount256)  阅读(1336)  评论(1编辑  收藏  举报