Assembly 直接推动常数或Mov Eax和推动Eax
直接为调用函数推送一个常量值,而不是将该值移动到eax和推送eax,这是有区别的 例如,在C中执行此操作: GetStdHandle(标准输出句柄) 许多编译器都会生成以下内容:Assembly 直接推动常数或Mov Eax和推动Eax,assembly,Assembly,直接为调用函数推送一个常量值,而不是将该值移动到eax和推送eax,这是有区别的 例如,在C中执行此操作: GetStdHandle(标准输出句柄) 许多编译器都会生成以下内容: ;B8 F5 FF FF FF MOV EAX,-11 ;50 PUSH EAX CALL GetStdHandle 我用的是手工的 ;6A F5 PUSH -11 CALL GetStdHandle 直接推送值是错误的,而不是将其加载到eax并推送eax?假设代码处于32位模式,您所拥有的应该是正常的 您可
;B8 F5 FF FF FF
MOV EAX,-11
;50
PUSH EAX
CALL GetStdHandle
我用的是手工的
;6A F5
PUSH -11
CALL GetStdHandle
直接推送值是错误的,而不是将其加载到eax并推送eax?假设代码处于32位模式,您所拥有的应该是正常的 您可以显式指定32位立即数,但对于Visual Studio(2005)汇编程序(ML.EXE),它使用了完整的32位操作数大小,而不是符号扩展字节值:
; 68 F5 FF FF FF
;
push dword ptr -11
即使使用Visual Studio的汇编程序(ML.EXE)指定字节ptr也可以:
但是,使用单词ptr会产生66前缀和16位推送(ESP减去2而不是4):
在这种情况下,66前缀将操作数大小(推送到堆栈上的值)更改为16位。来自英特尔手册:“如果源操作数是立即数,且其大小小于操作数大小,则将符号扩展值推送到堆栈上。”。所以在实践中,他仍然在堆栈上放置一个32位的值(假设OP正在构建一个32位的可执行文件)。你现在做的很好。
; 6A F5
;
push byte ptr -11
; 66 68 F5 FF
;
push word ptr -11