有没有办法防止 MASM 更改指令?

Posted

技术标签:

【中文标题】有没有办法防止 MASM 更改指令?【英文标题】:Is there a way to prevent MASM changing instructions? 【发布时间】:2020-08-16 01:33:37 【问题描述】:

我正在编写一个 C++ 程序,并决定在 x86 汇编中编写特定函数会更有效,因为它使用了进位标志。在反汇编中,我注意到一些指令被更改,导致我的程序抛出异常:“访问冲突读取位置”。为什么说明会发生变化,我该如何防止这种情况发生?

这是我的代码的 sn-p:

XOR EBX, EBX                ; 31 DB
MOV BL, DH                  ; 88 F3
MOV AH, BYTE PTR [ECX]      ; 8A 21

反汇编程序显示:

xor bx, bx                  ; 66 31 DB
mov bl, dh                  ; 88 F3
mov ah, byte ptr [bx+di]    ; 67 8A 21

【问题讨论】:

【参考方案1】:

您在 16 位模式下组装并在 32 位模式下反汇编,使一切都与应有的相反。 MASM 不会“更改”指令,只是将它们组装成您告诉它组装的模式。

例如在 16 位模式下,[ECX] 需要一个 67 地址大小覆盖前缀来编码 32 位寻址模式。在 32 位模式下解码时,相同的前缀会覆盖它以表示 16 位。 (并且该位模式意味着[bx+di];16 位寻址模式不能使用 SIB 字节,因此所有不同的寄存器组合都被打包到 ModRM 字节中。[cx] 不可编码。)


此外,如果您认为 xor + mov 是将 DH 零扩展为 EBX 的最有效方法,请查看movzx。这在现代 CPU 上效率更高。 (见https://agner.org/optimize/ 和https://uops.info/)。

一般你要避免写像AH这样的高8位寄存器; Haswell/Skylake 在读取完整寄存器时有合并惩罚,AMD CPU 有错误依赖。使用前请仔细阅读Why doesn't GCC use partial registers? 上的信息和链接。

【讨论】:

以上是关于有没有办法防止 MASM 更改指令?的主要内容,如果未能解决你的问题,请参考以下文章

来自 NASM 的 %line 指令等效于 MASM

Linux下的MASM?

使用 TYPE 指令汇编 MASM x86

.STACK 没有在 MASM 中分配正确的大小

MASM汇编 - REAL4浮点指令

为啥在 MASM 汇编中使用 FPU x87 指令集执行操作时得到无意义的数字?