有没有办法防止 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 更改指令?的主要内容,如果未能解决你的问题,请参考以下文章