-1

アセンブリ NASM を使用して、最も単純な WinAPI ウィンドウを作成しようとしています。Window Proc に問題があります。コメント行を見てください:

%マクロ API 2
    %1 %2 をインポート
    外部 %1
%endマクロ

API GetModuleHandleA、kernel32.dll
API LoadIconA,user32.dll
API LoadCursorA,user32.dll
API RegisterClassExA、user32.dll
API CreateWindowExA、user32.dll
API MessageBoxA、user32.dll
API SendMessageA、user32.dll
API DefWindowProcA、user32.dll
API ExitProcess、kernel32.dll
API GetMessageA、user32.dll
API DispatchMessageA、user32.dll
API TranslateMessage,user32.dll
API ShowWindow,user32.dll
API UpdateWindow,user32.dll
API GetCommandLineA、kernel32.dll
API PostQuitMessage,user32.dll

セグメント .data USE32
    windowName db "Hello world!", 0
    cmdLine dd 0
    hWnd dd 0
    hInst dd 0
    hCursor dd 0
    className db "moje_okno",0

    blad db "Blad!!!",0

セグメント.bss
    構造体 WNDCLASSEX
        .sSize resb 4
        .style resb 4
        .wndProc resb 4
        .clsExtra resb 4
        .wndExtra resb 4
        .hインスタンス resb 4
        .hIcon resb 4
        .hCursor resb 4
        .background resb 4
        .sMenuName resb 4
        .sClassName resb 4
        .hIconSm resb 4
    エンドストラクチャー

    wndClass istruc WNDCLASSEX
    エンド

グローバル..開始
セグメント .text USE32
..始める:
    プッシュ 0
    [GetModuleHandleA] を呼び出す
    mov dword [hInst], eax ; アプリケーション ハンドル

    dword 0x00007f00 をプッシュします。MakeINTRESOURCE(32512)
    dword 0 をプッシュ
    [LoadCursorA] を呼び出す
    mov dword [hCursor], eax ; カーソルハンドル

    mov dword [wndClass + WNDCLASSEX.sSize], dword 48 ; 構造体サイズ
    mov dword [wndClass + WNDCLASSEX.style], dword 0 ; スタイル
    mov dword [wndClass + WNDCLASSEX.wndProc], wndproc ; ウィンドウ プロシージャ
    mov dword [wndClass + WNDCLASSEX.clsExtra]、dword 0
    mov dword [wndClass + WNDCLASSEX.wndExtra]、dword 0
    mov eax, dword [hInst]
    mov dword [wndClass + WNDCLASSEX.hInstance]、eax ; 扱う
    mov dword [wndClass + WNDCLASSEX.hIcon]、dword 0
    mov eax, dword [hCursor]
    mov dword [wndClass + WNDCLASSEX.hCursor], eax
    mov dword [wndClass + WNDCLASSEX.background]、dword 0
    mov dword [wndClass + WNDCLASSEX.sMenuName]、dword 0
    mov dword [wndClass + WNDCLASSEX.sClassName], className ; クラス名
    mov dword [wndClass + WNDCLASSEX.hIconSm]、dword 0

    wndClass をプッシュ
    [RegisterClassExA] を呼び出す
    sprawdz_blad の近くを呼び出します。RegisterClassExA の戻り値を確認する

    プッシュ 0 ; パラメータ
    プッシュ dword [hInst] ; 扱う
    プッシュ 0 ;hMenu
    プッシュ 0 ;親
    プッシュ 200 ; 高さ
    プッシュ 200 ;幅
    プッシュ 200 ;y
    プッシュ 200 ;x
    プッシュ 0 ;スタイル
    push className ; ウィンドウ名
    push className ;ウィンドウ クラス
    プッシュ 0 ; 拡張スタイル
    [CreateWindowExA] を呼び出す
    eaxを押す
    sprawdz_blad の近くを呼び出します。CreateWindowExA の戻り値を確認します。戻り値 0

    プッシュ 0
    [ExitProcess] を呼び出す

wndproc:
    ; ここで、WINDOW PROC パラメータにアクセスする必要があります: HWND、MSG、WPARAM、LPARAM
    ; 私は試した:
     ポップイークス
     ポップ ebx
     ポップecx
     ポップEDX
    ; しかし、それは機能しません
    ; これらのレジストリには正しい値がありません


    戻る

箱:
    プッシュ 0
    ブラッドを押す
    ブラッドを押す
    プッシュ 0
    [MessageBoxA] を呼び出す
    戻る

sprawdz_blad:
    ポップイークス
    cmp eax, 0
    大丈夫です。関数が 0 を返す場合、すべて問題ありません

    プッシュ 0
    ブラッドを押す
    ブラッドを押す
    プッシュ 0
    [MessageBoxA] を呼び出す

    プッシュ 1
    [ExitProcess] を呼び出す
わかった:
    戻る


私はそれを何時間も機能させようとしますが、アイデアがありません。助けてください。ごきげんよう、ミハル。

4

1 に答える 1

2

呼び出されたサブルーチンは、自分で呼び出すか、Windowsによって呼び出されるか(wndprocなど)、スタックの最初のものとしてリターンアドレスを持ちます。あなたはこれをポップしたくない!パラメータにアクセスするには、スタックをさらに検索する必要があります。次のようなものを試してください...

wndproc:
    mov eax, [esp + 4]
    mov ebx, [esp + 8]
 ; etc...

それが役立つかどうかを確認してください...

最高、フランク

于 2012-06-28T03:25:36.690 に答える