0

_AddPS関数はスタックのバランスを崩し、StdCAllを対象としています。それ以上の情報はありません。これは、アセンブラーコードの2番目の部分にすぎません(最初は、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.
4

2 に答える 2

2

2 つのスタック フレームを作成しています! MASM でキーワードを使用しPROCてプロシージャを作成すると、MASM は標準のプロローグとエピローグを作成します。最初の 2 行は MASM 生成のプロローグで、最後の 2 行はプロローグです。

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 を見れば、間違いに気付くでしょう。

于 2013-03-10T04:59:43.653 に答える
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のコードです: ここに画像の説明を入力してください

違いがわかりますか?????

したがって、スタックは不均衡ではなく、パラメーターは期待した場所にありません。

スタックが本当に不均衡であるかどうかを知りたい場合はesp、関数の呼び出しの前と後の値を出力します。値が異なる場合は、スタックが不均衡です。

于 2013-03-10T16:48:36.827 に答える