玩了一下 Turbo Assembler 和 Turbo Debugger,我对操作码感到惊讶。更准确地说,我有一些汇编的二进制文件,其中 Turbo Debugger 反汇编了单词
29 C3
正确地sub bx, ax
。然而,Turbo Assembler 汇编了完全相同的指令sub bx, ax
到下面的词
2B D8
正疑惑着这个问题,我发现this https://c9x.me/x86/html/file_module_x86_id_308.html引用指出从寄存器中减去寄存器确实可以从两者开始29
and 2B
。事实是否确实如此exactly同一条指令可以用不同的操作码表示吗?如果是这样,那是为什么呢?是因为历史原因和兼容性吗?该参考文献规定了操作码的不同操作数类型,它们只是一致的sub bx, ax
。这是为了以后能够通过自修改代码等修补不同的操作数吗?此外,Turbo Assembler 是否具有语法结构来选择一种操作码而不是另一种操作码?
Note:我知道条件跳转就像je
and jz
具有相同的操作码,因为它们具有相同的依赖于标志的行为,并且不同的助记符反映了同一操作的不同语义,但前者让我感到困惑。
大多数 x86 指令支持两个操作数,其中一个操作数可以是内存操作数。这是通过将操作数编码为modr/m字节。该字节始终编码一个寄存器操作数和一个寄存器或存储器(r/m)操作数,但指令必须决定其操作数中哪个是寄存器操作数,哪个是存储器操作数。
因此,为了支持在源操作数或目标操作数中具有存储器操作数,可以使用许多指令,其中一种变体是源操作数可以是存储器操作数,而另一种变体是目标操作数可以是存储器操作数。这个一般是通过位来控制的01
(在一些手册中称为 d 位)。
因此,不需要内存操作数的指令可以采用两种方式进行编码,并且汇编器通常会选择一种或另一种作为稍微随机的实现细节。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)