简单指令编码
Simple instruction encode
让我们采用以下汇编指令:
add %cl,%bl
二进制编码为:00
cb
或 00000000
11001011
。将 cb
放入 ModR/M 位域,它看起来像:
1 1 0 0 1 0 1 1
+---+---+---+---+---+---+---+---+
| mod | reg | r/m |
+---+---+---+---+---+---+---+---+
并且,客栈查找register field here我们得到:
- mod:
11
(注册地址 mode)
- reg:
001
(cl 寄存器)
- r/m:
011
(bl 寄存器)
而且,我相信 000000ds
是 add
指令,而 d=s=0
因为它们都是寄存器。这是对该指令编码方式的正确理解吗?此外,对于 'full encoding' 方案,以下是否准确(以字节而不是位为单位):
[empty] 0x0 0b11001011 [empty] [empty] [empty]
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
Prefix Instruction Mod-reg-r/m Scale displacement immediate
我在尝试 'decoding' 指令时是否遗漏了什么?
是的,看起来不错。
用于编码 op r/m, r
与 op r, r/m
以及 8 位与 16/32 位的一般模式(用于可追溯到 8086 的“传统”ALU 指令)确实使用低常规模式中的 2 位操作码字节,但没有必要依赖它。
英特尔在他们的第 2 卷手册中确实完整地记录了每条指令的每种编码的确切情况。请参阅 Op/En 列和 add
for example. (See also https://ref.x86asm.net/coder64.htm 的操作数编码 table,其中还指定了每个操作码的操作数)。这些都让您知道哪些操作码采用 ModRM 字节,哪些不采用。
这些当然要用Intel-syntax命令。尝试遵循手册和教程,同时使用 AT&T 语法,这种语法颠倒了 operand-list 与 Intel 和 AMD 手册的顺序,这让您的生活变得更加复杂。
例如00 /r
是listed作为MR
操作数编码,从table中我们可以看出是操作数1=ModRM:r/m (r, w)
,所以是读写的,编码为r/m
字段。操作数 2 = ModRM:reg (r)
,因此它是由 reg
字段编码的 read-only 源。
有趣的事实:00 00
是 add [rax], al
,或 AT&T add %al, (%rax)
请注意,您可以要求 GAS 选择任一编码:
{load} add %cl,%bl # 02 d9
{store} add %cl,%bl # 00 cb
另见
让我们采用以下汇编指令:
add %cl,%bl
二进制编码为:00
cb
或 00000000
11001011
。将 cb
放入 ModR/M 位域,它看起来像:
1 1 0 0 1 0 1 1
+---+---+---+---+---+---+---+---+
| mod | reg | r/m |
+---+---+---+---+---+---+---+---+
并且,客栈查找register field here我们得到:
- mod:
11
(注册地址 mode) - reg:
001
(cl 寄存器) - r/m:
011
(bl 寄存器)
而且,我相信 000000ds
是 add
指令,而 d=s=0
因为它们都是寄存器。这是对该指令编码方式的正确理解吗?此外,对于 'full encoding' 方案,以下是否准确(以字节而不是位为单位):
[empty] 0x0 0b11001011 [empty] [empty] [empty]
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
Prefix Instruction Mod-reg-r/m Scale displacement immediate
我在尝试 'decoding' 指令时是否遗漏了什么?
是的,看起来不错。
用于编码 op r/m, r
与 op r, r/m
以及 8 位与 16/32 位的一般模式(用于可追溯到 8086 的“传统”ALU 指令)确实使用低常规模式中的 2 位操作码字节,但没有必要依赖它。
英特尔在他们的第 2 卷手册中确实完整地记录了每条指令的每种编码的确切情况。请参阅 Op/En 列和 add
for example. (See also https://ref.x86asm.net/coder64.htm 的操作数编码 table,其中还指定了每个操作码的操作数)。这些都让您知道哪些操作码采用 ModRM 字节,哪些不采用。
这些当然要用Intel-syntax命令。尝试遵循手册和教程,同时使用 AT&T 语法,这种语法颠倒了 operand-list 与 Intel 和 AMD 手册的顺序,这让您的生活变得更加复杂。
例如00 /r
是listed作为MR
操作数编码,从table中我们可以看出是操作数1=ModRM:r/m (r, w)
,所以是读写的,编码为r/m
字段。操作数 2 = ModRM:reg (r)
,因此它是由 reg
字段编码的 read-only 源。
有趣的事实:00 00
是 add [rax], al
,或 AT&T add %al, (%rax)
请注意,您可以要求 GAS 选择任一编码:
{load} add %cl,%bl # 02 d9
{store} add %cl,%bl # 00 cb
另见