在汇编中,如何使用记录为小于本机寄存器宽度的 return 值来处理 Windows API?
In assembly, how to handle Windows API with a return value that's documented as less than native register width?
多年来,ntohs(32 位版本)有一个 return 值
这是零扩展到高 16 位(字)。但是,最近更新 Windows 10 后,有时会 return 上位词出现垃圾。
例如,将参数 0xF00D 传递给
call ntohs
return 值为
- EAX = 00F00DF0(32 位代码)
- RAX = 0000000000000DF0(64 位代码)
MASM 代码中的修复是使用 movzx(与 MSVC 相同)
零扩展 return 寄存器
call ntohs
movzx eax, ax
问题
任何 Windows API 的 return 值被记录为小于本机寄存器宽度是否正确,不能保证高位被清零,即return RAX = 0000000000000DF0(64 位)中的值很可能是巧合?
至少对于 x64,高位未定义,如果需要,调用者负责进行零或符号扩展。如果您的代码依赖于高位为零,恐怕它一直都是错误的,到目前为止您很幸运。
https://docs.microsoft.com/en-us/cpp/build/x64-calling-convention?view=msvc-160
The state of unused bits in the value returned in RAX or XMM0 is undefined.
多年来,ntohs(32 位版本)有一个 return 值 这是零扩展到高 16 位(字)。但是,最近更新 Windows 10 后,有时会 return 上位词出现垃圾。
例如,将参数 0xF00D 传递给
call ntohs
return 值为
- EAX = 00F00DF0(32 位代码)
- RAX = 0000000000000DF0(64 位代码)
MASM 代码中的修复是使用 movzx(与 MSVC 相同)
零扩展 return 寄存器call ntohs
movzx eax, ax
问题
任何 Windows API 的 return 值被记录为小于本机寄存器宽度是否正确,不能保证高位被清零,即return RAX = 0000000000000DF0(64 位)中的值很可能是巧合?
至少对于 x64,高位未定义,如果需要,调用者负责进行零或符号扩展。如果您的代码依赖于高位为零,恐怕它一直都是错误的,到目前为止您很幸运。
https://docs.microsoft.com/en-us/cpp/build/x64-calling-convention?view=msvc-160
The state of unused bits in the value returned in RAX or XMM0 is undefined.