Assembly 直接推动常数或Mov Eax和推动Eax

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位模式,您所拥有的应该是正常的 您可

直接为调用函数推送一个常量值,而不是将该值移动到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位模式,您所拥有的应该是正常的

您可以显式指定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