8086(16位)汇编指令与机器码转换原理

8086(16位)汇编指令与机器码转换原理

  • 1 16位寻址形式下的ModR/M字节
  • 2 汇编指令转机器码
    • 2.1 mov al, 3
    • 2.2 mov cx, 3
    • 2.3 mov edx, 3
    • 2.4 mov cx,[0100h]与mov [0100h],cx
    • 2.5 mov ax,cx与mov cx,ax
    • 2.6 mov cx,[bx]
    • 2.7 mov cx,[bx+si]
    • 2.8 mov cx,[bx+10h]
    • 2.9 mov cx,[bx+si+10h]
    • 2.10 mov cx,[bx+0100h]
    • 2.11 mov cx,[bx+si+0100h]

本文属于《 X86架构指令基础系列教程》之一,欢迎查看其它文章。
在上一节,我们讲了X86指令基本格式。在8086架构下,是不存在SIB字节的,因此,我们重点关注ModR/M。

1 16位寻址形式下的ModR/M字节

ModR/M由Mod + RM + Reg/Opcode三部分组成,如下所示:
8086(16位)汇编指令与机器码转换原理_第1张图片
许多指令的机器码组成中都需要使用ModR/M字段,8086 CPU为16位寻址,因此需要了解16位寻址形式下的ModR/M字节具体值,组成情况,如下图所示。
8086(16位)汇编指令与机器码转换原理_第2张图片
ModR/M表查询方法:

  • Mod值,在上表蓝框中Mod列下,可以是00、01、10、11共4种。
  • R/M值,在上表蓝框中R/M列下,可以是000、001、010、011、100、101、110、111共8种;Mod字段与R/M字段组合,形成32个可能的值:8个寄存器和24种寻址模式。
  • Reg/Opcode值,在上表红框中(AX、CX、DX、…),可以是000、001、010、011、100、101、110、111共8种。

类似于坐标的方式,通过Mod和R/M值来确定哪一行,Reg/Opcode值来确定哪一列,所交汇的单元格,就是ModR/M字节的值。

比如:

Mod为00,R/M为011,对应的寻址方式为[bp+di];
Reg/Opcode为001,表示CL/CX/ECX/MM1寄存器或操作,所组成的ModR/M值为0Bh。

2 汇编指令转机器码

如果想了解指令的机器码,就需要了解 x86 处理器的指令集。
要想了解 x86 处理器的指令集,Intel 的官方资料是必不可少的,下面是 x86 架构软件开发手册,可以从这里下载。
8086(16位)汇编指令与机器码转换原理_第3张图片
我们举几个立即数操作的例子:

mov al, 3
mov cx, 3
mov edx, 3

然后,把表格中每一类寻址方式,都举一个例子,进行描述,如下:

序号 寻址方式 Mod R/M 汇编例子
1 disp16 00 110 mov cx,[0100h]与mov [0100h],cx
2 [BX] 00 111 mov cx,[bx]
3 [BX+SI] 00 000 mov cx,[bx+si]
4 [BX]+disp8 01 111 mov cx,[bx+10h]
5 [BX+SI]+disp8 01 000 mov cx,[bx+si+10h]
6 [BX]+disp16 10 111 mov cx,[bx+0100h]
7 [BX+SI]+disp16 10 000 mov cx,[bx+si+0100h]
8 ECX/CX/CL/MM1 11 001 mov ax,cx
9 EAX/AX/AL/MM0 11 000 mov cx,ax

因此,一共有12个汇编指令转机器码的例子,接下来,依次来讲解。

通常将一条汇编指令,转换为机器码,需要经过如下几个步骤:

  • 找到汇编指令对应的操作码;
  • 查询ModR/M表,确定ModR/M值;
  • 查询SIB表,确定SIB值。
  • 确定其他偏移、立即数等,最终组合成为一串二进制码。

2.1 mov al, 3

8086(16位)汇编指令与机器码转换原理_第4张图片
mov al, 3表示将立即数3存储到8位寄存器al中。
查询指令手册,与MOV r8,imm8指令相符,其操作码为B0+rb,rb表示目的操作数r8寄存器的编号。
当前指令的r8,就是al,al编号为0,因此操作码为B0+0=B0。
8086(16位)汇编指令与机器码转换原理_第5张图片
上面的编号,每个数字都代表了一组寄存器。比如:数字 0 代表了 AL、AX、EAX、MM0这一组寄存器;数字 1 代表了 CL、CX、ECX、MM1这一组寄存器;依此类推。

根据X86指令基本格式定义,当前指令不存在Instruction Prefixes、ModR/M、SIB和Displacement,如下:
在这里插入图片描述
目前mov指令和al寄存器,都在操作码中体现了,但是立即数还没有体现,因此指令的机器码组成,如下所示:

汇编指令 操作码 立即数 机器码
mov al,3 B0 3 B003

2.2 mov cx, 3

mov cx, 3表示将立即数3存储到16位寄存器cx中。
查询指令手册,与MOV r16,imm16指令相符,其操作码为B8+ rw,rw表示目的操作数r16寄存器的编号。
在这里插入图片描述
当前指令的r16,就是cx,cx编号为1,因此操作码为B8+1=B9。
根据X86指令基本格式定义,当前指令不存在Instruction Prefixes、ModR/M、SIB和Displacement。
目前mov指令和cx寄存器,都在操作码中体现了,但是立即数还没有体现,因此指令的机器码组成,如下所示:

汇编指令 操作码 立即数 机器码
mov cx, 3 B9 3 B90300

机器码左边为低地址,右边为高地址,为了存储16位形式的0003h,需要将高8位00h放入高地址,低8位03h放入低地址,因此立即数表示为0300h。

2.3 mov edx, 3

mov edx, 3表示将立即数3存储到32位寄存器edx中。
查询指令手册,与MOV r32,imm32指令相符,其操作码为B8+ rd,rd表示目的操作数r32寄存器的编号。
在这里插入图片描述

当前指令的r32,就是edx,edx编号为2,因此操作码为B8+2=BA。
根据X86指令基本格式定义,当前指令不存在Instruction Prefixes、ModR/M、SIB和Displacement。
目前mov指令和edx寄存器,都在操作码中体现了,但是立即数还没有体现,因此指令的机器码组成,如下所示:

汇编指令 操作码 立即数 机器码
mov edx, 3 BA 3 BA03000000

2.4 mov cx,[0100h]与mov [0100h],cx

mov cx,[0100h],段地址默认在ds中,表示将ds * 16 + 0100h位置处内存单元数据(2字节),存储到16位寄存器cx中。
查询指令手册,与MOV r16,r/m16指令相符,其操作码为8B /r,/r表示这条指令具有ModR/M字段。
在这里插入图片描述
因此,我们查询ModR/M表,如下图所示:
8086(16位)汇编指令与机器码转换原理_第6张图片
我们首先分析指令mov cx,[0100h]的组成,目的操作数为cx,源操作数为[0100h];表格中disp16的意思是Displacement16,即16位的偏移,汇编中[0100h]正是disp16,比如[10h]就是disp8,[00010000h]就是disp32。
因此,以disp16为行,以CX为列,交汇处0E表示ModR/M值(Mod=00,Reg/Opcode=001,R/M=110)。
目前mov指令和cx寄存器,都在操作码中体现了,但是立即数0100h还没有体现,因此指令的机器码组成,如下所示:

汇编指令 操作码 ModR/M 立即数 机器码
mov cx,[0100h] 8B 0E 0100 8B0E0001

机器码中,0100h,仍然保持低字节放在低地址,高字节放在高地址。

mov cx,ds:[0100h]mov cx,cs:[0100h],其机器码也是8B0E0001,唯一的区别是所使用的段寄存器不一样,前者是cx = ds * 16 + 0100h,后者是cx = cs * 16 + 0100h。

另外,试想一下mov [0100h],cx,又该如何查询ModR/M表?
在这里插入图片描述
此时,其操作码为89 /r。查ModR/M表时,实际上还是以disp16为行,以CX为列,来定位ModR/M值,依旧为0E。

汇编指令 操作码 ModR/M 立即数 机器码
mov [0100h],cx 89 0E 0100 890E0001

我们可以看出,当内存与寄存器之间进行数据操作时,ModR/M值与写入的方向无关,此时写入方向是由操作码来进行区别的。

所以,我们查ModR/M表时,需要重点注意:

  • 情况1,内存与寄存器之间进行数据操作的指令,必须以内存寻址方式为行,以寄存器操作数为列,去定位ModR/M值;
  • 情况2,寄存器与寄存器之间进行数据操作的指令,必须以源操作数为行,以目的操作数为列,去定位ModR/M值。

情况1,内存与寄存器进行数据操作,如下图所示:
8086(16位)汇编指令与机器码转换原理_第7张图片
情况2,寄存器与寄存器进行数据操作,如下图所示:
8086(16位)汇编指令与机器码转换原理_第8张图片
情况2,具体分析见mov ax,cx与mov cx,ax指令。

2.5 mov ax,cx与mov cx,ax

mov ax,cx,表示将cx寄存器内容存储到ax寄存器中。
查询指令手册,与MOV r16,r/m16指令相符,其操作码为8B /r,/r表示这条指令具有ModR/M字段。
在这里插入图片描述
因此,我们查询ModR/M表,如下图所示:
8086(16位)汇编指令与机器码转换原理_第9张图片
以源操作数cx为行,以目的操作数ax为列,交汇处C1表示ModR/M值。
因此指令的机器码组成,如下所示:

汇编指令 操作码 ModR/M 机器码
mov ax,cx 8B C1 8BC1

另外,mov cx,ax指令,其操作码也为8B /r,查询ModR/M表,如下图所示:
8086(16位)汇编指令与机器码转换原理_第10张图片
以源操作数ax为行,以目的操作数cx为列,交汇处C8表示ModR/M值。
因此指令的机器码组成,如下所示:

汇编指令 操作码 ModR/M 机器码
mov cx,ax 8B C8 8BC8

我们可以看出,当寄存器与寄存器之间进行数据操作时,ModR/M值决定了,目的和源操作数所使用的是哪个寄存器,以及寄存器写入的方向。

2.6 mov cx,[bx]

mov cx,[bx],表示将bx寄存器中地址,指向的内存单元,存储到cx寄存器中。
查询指令手册,与MOV r16,r/m16指令相符,其操作码为8B /r,/r表示这条指令具有ModR/M字段。
在这里插入图片描述
因此,我们查询ModR/M表,以[bx]为行,以cx为列,交汇处0F表示ModR/M值。
因此指令的机器码组成,如下所示:

汇编指令 操作码 ModR/M 机器码
mov cx,[bx] 8B 0F 8B0F

2.7 mov cx,[bx+si]

mov cx,[bx+si],表示将bx寄存器中地址+si寄存器中地址,指向的内存单元,存储到cx寄存器中。
MOV r16,r/m16指令相符,其操作码为8B /r。

查ModR/M表,以[bx+si]为行,以cx为列,交汇处08表示ModR/M值。
因此指令的机器码组成,如下所示:

汇编指令 操作码 ModR/M 机器码
mov cx,[bx+si] 8B 08 8B08

2.8 mov cx,[bx+10h]

mov cx,[bx+10h],表示将bx寄存器中地址+10h,指向的内存单元,存储到cx寄存器中。
MOV r16,r/m16指令相符,其操作码为8B /r。

查ModR/M表,以[bx]+disp8为行,以cx为列,交汇处4F表示ModR/M值。
因此指令的机器码组成,如下所示:

汇编指令 操作码 ModR/M 立即数 机器码
mov cx,[bx+10h] 8B 4F 10 8B4F10

2.9 mov cx,[bx+si+10h]

mov cx,[bx+si+10h],表示将bx寄存器中地址+si寄存器中地址+10h,指向的内存单元,存储到cx寄存器中。
MOV r16,r/m16指令相符,其操作码为8B /r。

查ModR/M表,以[bx+si]+disp8为行,以cx为列,交汇处48表示ModR/M值。
因此指令的机器码组成,如下所示:

汇编指令 操作码 ModR/M 立即数 机器码
mov cx,[bx+si+10h] 8B 48 10 8B4810

2.10 mov cx,[bx+0100h]

mov cx,[bx+0100h],表示将bx寄存器中地址+0100h,指向的内存单元,存储到cx寄存器中。
MOV r16,r/m16指令相符,其操作码为8B /r。

查ModR/M表,以[bx]+disp16为行,以cx为列,交汇处8F表示ModR/M值。
因此指令的机器码组成,如下所示:

汇编指令 操作码 ModR/M 立即数 机器码
mov cx,[bx+0100h] 8B 8F 0100 8B8F0001

2.11 mov cx,[bx+si+0100h]

mov cx,[bx+si+0100h],表示将bx寄存器中地址+si寄存器中地址+0100h,指向的内存单元,存储到cx寄存器中。
MOV r16,r/m16指令相符,其操作码为8B /r。

查ModR/M表,以[bx+si]+disp16为行,以cx为列,交汇处88表示ModR/M值。
因此指令的机器码组成,如下所示:

汇编指令 操作码 ModR/M 立即数 机器码
mov cx,[bx+si+0100h] 8B 88 0100 8B880001

参考文档:

  • 《x86汇编语言》学习11 指令的格式及其操作尺寸
  • Intel Architecture Software Developer’s Manual

你可能感兴趣的:(X86指令集,汇编,机器码,X86指令)