计算机结构之X86指令集编码

X86指令集编码

前言

在学习了解计算机结构时,针对X86指令从汇编码到机器码的转换过程详解。

例题入手

在下方表格[1]里可以看到部分X86 ALU(Arithmetic Logic Unit)指令的操作码
表格1
表格[1]

下方表格[2]是部分寄存器位置对应的编码值,由于小编采用的是德国的教材,所以表格内部分文字描述是德语,我已对其翻译,不用担心。在这里插入图片描述

表格[2]

以下表格[3]是Mod R/M Byte编码格式
在这里插入图片描述
表格[3]

以上信息为题干信息,现在来看求解题目:
根据给出的操作码(第一列)以及编码长度(第3列)求其对应的机器编码(第二列)
在这里插入图片描述

  1. AND eax, 0
    首先根据指令得出操作码为 AND,然后Scr.1为寄存器eax, Scr.2是0为1Byte的立即操作数,在表格[1]中找到操作码AND对应的值为0x83/4 (0x83是操作码,4是偏移量)

    由于是eax,0 属于寄存器直接寻址所以Mod的值为11当Mod值为11时(即寄存器直接寻址),Reg对应的是源寄存器,R/M对应的是目标寄存器, 其余情况下Reg对应的是目标寄存器,R/M对应的是源寄存器。 所以有偏移量4所以Reg.对应为100,R/M为000

    ModRegR/M
    11100000

    Mod R/M 码段对应的16进制为e0,整个指令的机器码为操作码 0x83 + e0 +立即操作数的16进制形式 00 = 0x83e000。如果立即操作数为10则将最后两位改为0a

2. MOV ebx, [ecx]
首先根据指令得出操作码为 MOV,然后Scr.1为寄存器ebx, Scr.2表示寄存器存储的是地址,在表格[1]中找到操作码MOV对应的值为0x8B

由于是ebx, [ecx]属于 寄存器非直接寻址所以Mod的值为00当Mod值为00时(即寄存器非直接寻址),Reg对应的是目标寄存器,R/M对应的是源寄存器。 根据表[2]ebx为011 所以Reg为011,ecx 为001,所以R/M为001

ModRegR/M
00011001

对应的16进制为19

Mod R/M 码段对应的16进制为19,整个指令的机器码为操作码0x8B19。

3. ADD ebx, [ecx+4]
首先根据指令得出操作码为 ADD,然后Scr.1为寄存器ebx, Scr.2表示寄存器存储的是地址加上偏移量4,在表格[1]中找到操作码MOV对应的值为0x03

由于是ebx, [ecx+4]属于 寄存器非直接寻址且有偏移所以Mod的值根据表格[2]为01Reg对应的是目标寄存器,R/M对应的是源寄存器。 根据表[2]ebx为011 所以Reg为011,ebx 为011,R/M为001

ModRegR/M
01011001

对应的16进制为59

Mod R/M 码段对应的16进制为59,然后在末尾加上位移4的16进制码为04,所以整个指令的机器码为操作码0x035904。

4. AND eax, ebx
首先根据指令得出操作码为 AND,然后Scr.1为寄存器eax, Scr.2表示寄存器ebx,在表格[1]中找到操作码MOV对应的值为0x21

由于eax, ebx属于 寄存器直接寻址所以Mod的值为11当Mod值为1时(即寄存器直接寻址),Reg对应的是源寄存器,R/M对应的是目标寄存器。 根据表[2]eax为000 所以R/M为000,ebx 为011,所以Reg为011

ModRegR/M
11011000

对应的16进制为d8

Mod R/M 码段对应的16进制为d8,整个指令的机器码为操作码0x21d8。

5. MOV ebx, [ecx +8]
参考 ADD exb, [ecx+8] ,结果为0x8b5908
6. OR eax, ebx
参考 AND eax, ebx, 结果为0x09d8
7. SUB eax, 200
首先根据指令得出操作码为 SUB,然后Scr.1为寄存器eax, Scr.2表示立即操作数200,在表格[1]中找到操作码SUB对应的值为0x2d(因为200是对应的4Byte)

这里由于立即操作数是200所以用4Byte表示为c8 00 00 00,这是SUB针对立即操作数比较特殊的地方,此时Mod R/M不再适用。

直接得出结果是 0x2dc8000000.

  1. SUB eax, 1;对应的编码长(Codelang) 为3B(补充题)
    当立即操作数是1Byte时,例子是1 ,此时按照之前正常的逻辑进行处理如下:
    根据表格[1] 操作码是SUB, 然后Scr.1为寄存器eax, Scr.2表示立即操作数1,在表格[1]中找到操作码SUB对应的值为0x83/5 (操作码为0x83,有偏移量5)

由于eax, 1属于 寄存器直接寻址所以Mod的值为11当Mod值为1时(即寄存器直接寻址),Reg对应的是源寄存器,R/M对应的是目标寄存器。 根据表[2]eax为000 所以R/M为000,Reg为偏移量5, 101

ModRegR/M
11101000

对应的16进制为e8

所以整个应该就是操作码0x83+e8+01(偏移量)=0x83e801.

当立即操作数为4Byte时和1Byte时,处理过程不一样,是因为 0x2D 是一个专用操作码,用于从 EAX 寄存器中减去 32 位立即数,所以立即数 200 必须被扩展为 32 位。由于历史原因,我们使用小端位数记数法来记录即时数据。在过去,当 16 位总线还很普遍的时候,可以用这种方式开始计算,因为转移是从最小有效位 (LSB) 计算到最大有效位 (MSB)(比较写入的乘法/加法)。

分析总结

除开SUB 操作码针对4Byte立即操作数时,适用Mod R/M 模型来处理;当Src.1 和Src.2都是寄存器时,属于寄存器直接寻址,Mod 为11,此时Reg和R/M的数据要进行互换一下,参考上面的例子;
如果是Src.1是寄存器,Src.2表示存储的是地址且无偏移量的情况下,那么就是非直接寻址,Mod 为00,如果在非直接寻址情况下,有偏移量,那么Mod就需要根据偏移量的大小参考表格[2]去选择是01还是10。然后Reg R/M 在剩余的3中情况下都不需要互换,参考上面的例子。

最后给大家提供一个用于检查从汇编码到机器码的转换的网站,可以验证自己是否正确转换。由于小编在G国,所以不确定这个网站国内是否适用,如果不适用的话请留言,谢谢!


欢迎阅读,以及欢迎指出不足之处,如果点赞就更好了;
祝您学习愉快~😊😊😊

  • 10
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值