我的stdcall汇编程序代码使堆栈失去平衡

时间:2013-03-09 21:17:32

标签: assembly x86

_AddPS函数使堆栈失衡,并且是StdCAll。我没有更多的信息,这只是我的第二段汇编程序代码(我的第一个是模拟cdecl函数调用的测试.exe)。

.386
.MODEL FLAT, STDCALL
option casemap :none    ; case sensitive

.CODE

_LibMain proc instance:dword, reason:dword, unused:dword
    mov     EAX, 1      ;
    ret
_LibMain endp

_AddPS proc a:dword, b:dword
    push    ebp         ;
    mov     ebp, esp    ;   // ebp << esp
    push    EAX         ;
    push    EBX         ;
    mov EAX, [ebp+8]    ;
    mov EBX, [ebp+4]    ;
    add     EAX, EBX    ;
    pop     EBX         ;
    pop     EAX         ;
    mov     esp, ebp    ;
    pop ebp     ;
    RET 8
_AddPS endp
END _LibMain

使用MASM和以下命令行编译:

c:\Asm\Test.asm /coff /Gz /FeC:\Asm\Test.dll /FoC:\Asm\Test.obj /link /SUBSYSTEM:WINDOWS /link /DLL

编辑:以下代码有效,但我对其原因感到朦胧:

_Test proc a:dword, b:dword
    push    ebp     ; Store the stack frame.
    push    EAX     ; Store EAX. Probably not needed. 
    mov EAX, a      ; Move a into EAX.
    add EAX, b      ; Add b to EAX.
    add esp, 4      ; Move past the stored EAX without popping.
    pop ebp     ; pop the stack frame.
    RET 8 // dword is 4 bytes in .386. We return past the parameters.
_Test endp // Marks where to stop compiling the function.

2 个答案:

答案 0 :(得分:2)

您正在创建 2 堆叠帧!当您在MASM中使用PROC关键字创建过程时,MASM会创建标准序言和结语! 前两行是MASM生成的序言,最后两行是你的序幕。

PUSH    EBP
MOV     EBP, ESP
PUSH    EBP
MOV     EBP, ESP

如果您想按照自己的方式进行编码并使用MASM创建手动堆栈帧并继续使用MASM过程,则需要关闭序言/结尾创建并在完成时将其重新打开。

这应该有效:

option prologue:none ; turn off default prologue creation
option epilogue:none ; turn off default epilogue creation
_AddPS proc a:dword, b:dword
    push    ebp         ;
    mov     ebp, esp    ;   // ebp << esp
    push    EAX         ;
    push    EBX         ;
    mov EAX, [ebp+8]    ;
    mov EBX, [ebp+4]    ;
    add     EAX, EBX    ;
    pop     EBX         ;
    pop     EAX         ;
    mov     esp, ebp    ;
    pop ebp     ;
    RET 8
_AddPS endp  
option prologue:PrologueDef ; turn on default prologue creation
option epilogue:EpilogueDef ; turn on default epilogue creation   

如果需要,你甚至可以让MASM使用你自己的特别序言/结语。

如果你在像olly这样的调试器中查看你的exe,你会发现错误。

答案 1 :(得分:1)

include masm32rt.inc
.code
start:
    int 3
    ret

_AddPSOrg proc a:dword, b:dword
    push    ebp         ;
    mov     ebp, esp    ;   // ebp << esp
    push    EAX         ;
    push    EBX         ;
    mov EAX, [ebp+8]    ;
    mov EBX, [ebp+4]    ;
    add     EAX, EBX    ;
    pop     EBX         ;
    pop     EAX         ;
    mov     esp, ebp    ;
    pop ebp     ;
    RET 8

_AddPSOrg endp  

option prologue:none ; turn off default prologue creation
option epilogue:none ; turn off default epilogue creation
_AddPSGood proc a:dword, b:dword
    push    ebp         ;
    mov     ebp, esp    ;   // ebp << esp
    push    EAX         ;
    push    EBX         ;
    mov EAX, [ebp+8]    ;
    mov EBX, [ebp+4]    ;
    add     EAX, EBX    ;
    pop     EBX         ;
    pop     EAX         ;
    mov     esp, ebp    ;
    pop ebp     ;
    RET 8
_AddPSGood endp  
option prologue:PrologueDef ; turn on default prologue creation
option epilogue:EpilogueDef ; turn on default epilogue creation     
end start

运行时,int 3会显示您的程序。这是olly中的代码: enter image description here

你能看出差异?????

因此,堆栈不是不平衡的,参数不是你期望的那样。

如果您想知道堆栈是否真的不平衡,请在调用函数之前和之后打印esp的值,如果值不同,则堆栈不平衡。