gpt4 book ai didi

assembly - 位移值对 ModRegRm 字节的 Mod 字段有什么影响?

转载 作者:行者123 更新时间:2023-12-03 08:45:20 26 4
gpt4 key购买 nike

我正在编写一个 8086 汇编器,它接受指令并生成 8086 机器代码。我使用《Intel 8086 用户手册》作为引用。

为了说清楚,我将解释一下情况。假设我想汇编这条指令 mov ax, bx。我查了一下手册,发现当mov的操作数是2个16bit寄存器时,mov的操作码是0x89,并指定操作数(源和目标),在本例中 mov 后跟一个 ModRegRm 字节,用于指定源和目标,在本例中为 0xd8。该字节二进制 = 11011000

Mod 为 2 位,Reg、Rm 各为 3 位。因此,Mod = 11,Reg = 011,Rm = 000。这里很简单,但有一点我不明白,那就是寻址模式和位移。

modregrm-table

查看表格和以下三个指令及其机器代码。

mov [bx+0x6], ax ;894706

mov [bx+0xbf],ax ;8987BF00

mov [bx+0xffff],ax ;8947FF

我假设每条指令的位移长度分别为8位、8位、16位,这是否错误?

我认为我是对的,因为很明显,0x60xbf 是 1 个字节,0xffff 是两个字节。

问题是,为什么第二条指令中的MOD字段是10b或0x02而不是01b或0x01?应该是0x01,因为位移是8位位移,不是吗?为什么第三条指令中的MOD是0x01,尽管位移是16位?为什么汇编器忽略其余的位移并仅捕获 1 个字节?

最佳答案

位移的大小取决于“MOD”字段(例如,如果 MOD=001b,则为 8 位;如果 MOD=010b,则为 16 位),并通过符号扩展至预期大小。

这意味着像 mov [bx+6], ax 这样的指令可以编码为 mov [bx+0x0006], ax (MOD=010b 和16 位位移)或者可以编码为 mov [bx+0x06], ax(MOD=001b 和 8 位位移)。

同样,mov [bx+65535],ax 可以以任何一种方式编码(8 位位移或 16 位位移);因为 0xFF 可以符号扩展为 0xFFFF。

但是; mov [bx+191],ax 不能编码为 8 位位移,因为当 191 (0xBF) 进行符号扩展时,它会变成 0xFFBF,不等于 191。它必须使用16 位位移。

本质上;如果完整 16 位位移的最高 9 位全部相同(值 0x0000 到 0x007F 全部清零,或者值 0xFF80 到 0xFFFF 全部设置),则可以将其编码为 8 位位移或 16 位位移;否则它必须使用 16 位位移。

当需要在不同的编码之间进行选择时;一个好的汇编器会选择最小的可能性(并使用 8 位位移,因为它使指令短 1 个字节)。如果避免了填充的需要(如果以下指令需要在某个边界上对齐),更好的汇编器可能会使用更大的版本。例如,考虑 .align 2 然后 mov [bx+6], ax 然后 .align 2 然后 clc - 对于较小的(3 字节)mov,您必须在 clc 之前插入额外的 nop 指令作为填充,以确保指令对齐2 字节边界(由 align 2 指令请求),而对于较大的(4 字节)mov 则不需要(因此少了 1 条指令,但结果代码的字节数相同)。

关于assembly - 位移值对 ModRegRm 字节的 Mod 字段有什么影响?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61707459/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com