はるき*_*はるき 1 x86 masm visual-c++
我正在编写一个 C++ 程序,并决定在 x86 程序集中编写特定函数会更有效,因为它使用了进位标志。在反汇编中,我注意到一些指令发生了变化,导致我的程序抛出异常:“访问冲突读取位置”。为什么说明会发生变化,我该如何防止这种情况发生?
这是我的代码片段:
XOR EBX, EBX ; 31 DB
MOV BL, DH ; 88 F3
MOV AH, BYTE PTR [ECX] ; 8A 21
Run Code Online (Sandbox Code Playgroud)
反汇编程序显示:
xor bx, bx ; 66 31 DB
mov bl, dh ; 88 F3
mov ah, byte ptr [bx+di] ; 67 8A 21
Run Code Online (Sandbox Code Playgroud)
您在 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 有错误依赖。阅读有关为什么 GCC 不使用部分寄存器的信息和链接?在您使用它们之前请仔细。
| 归档时间: |
|
| 查看次数: |
37 次 |
| 最近记录: |