1

ソースのコピーは次のとおりです。

extrn MessageBoxA: PROC
extrn ExitProcess: PROC

.data
mytit db 'The 64-bit world of Windows & assembler...', 0
mymsg db 'Hello World!', 0

.code
main proc
mov r9d, 0       ; uType = MB_OK
lea r8,  mytit   ; LPCSTR lpCaption
lea rdx, mymsg   ; LPCSTR lpText
mov rcx, 0       ; hWnd = HWND_DESKTOP
call MessageBoxA
mov ecx, eax     ; uExitCode = MessageBox(...)
call ExitProcess
main endp

End

今、私は「最初の」x64 アセンブリ プログラムを起動して実行しようとしているので、実際に遊んでアセンブリを学習できるようになります。正しく組み立てるためのものは何もありませんが、これまでのところ運がありません。

これをアセンブルすると、アセンブル時でも実行時でもエラーは発生しませんが、プログラムは想定どおりに実行されません。まったく何もしていないように見えます。実行可能ファイルが生成され、それをダブルクリックしても何も起こらず、タスク マネージャーにアクセスしてもバックグラウンドで実行されていないようです。どうしたの?

「Build Customizations...」の下の「masm」をチェックして生成される MASM64 の既定の設定を使用しており (ソリューション エクスプローラーでプロジェクトを右クリックすると見つかります)、構成マネージャーでプラットフォームを Win32 から x64 に変更します。例外は、「エントリ ポイント」リンカー オプションを「メイン」に変更し、「サブシステム」リンカー オプションを「Windows」に変更したことです。(これはすべて Visual Studio 2012 で行われます。)

Visual Studio でプログラムを実行して生成されるデバッグ情報は次のとおりです。

'Hello World (ASM).exe' (Win32): Loaded 'D:\Google Drive\My Documents\Visual Studio 
2012\Projects\Hello World (ASM)\x64\Release\Hello World (ASM).exe'. Symbols loaded.
'Hello World (ASM).exe' (Win32): Loaded 'C:\Windows\System32\ntdll.dll'. Cannot find or open the PDB file.
'Hello World (ASM).exe' (Win32): Loaded 'C:\Windows\System32\kernel32.dll'. Cannot find or open the PDB file.
'Hello World (ASM).exe' (Win32): Loaded 'C:\Windows\System32\KernelBase.dll'. Cannot find or open the PDB file.
'Hello World (ASM).exe' (Win32): Loaded 'C:\Windows\System32\user32.dll'. Cannot find or open the PDB file.
'Hello World (ASM).exe' (Win32): Loaded 'C:\Windows\System32\gdi32.dll'. Cannot find or open the PDB file.
'Hello World (ASM).exe' (Win32): Loaded 'C:\Windows\System32\imm32.dll'. Cannot find or open the PDB file.
'Hello World (ASM).exe' (Win32): Loaded 'C:\Windows\System32\msctf.dll'. Cannot find or open the PDB file.
'Hello World (ASM).exe' (Win32): Loaded 'C:\Windows\System32\msvcrt.dll'. Cannot find or open the PDB file.
'Hello World (ASM).exe' (Win32): Loaded 'C:\Windows\System32\nvinitx.dll'. Cannot find or open the PDB file.
'Hello World (ASM).exe' (Win32): Loaded 'C:\Windows\System32\advapi32.dll'. Cannot find or open the PDB file.
'Hello World (ASM).exe' (Win32): Loaded 'C:\Windows\System32\sechost.dll'. Cannot find or open the PDB file.
'Hello World (ASM).exe' (Win32): Loaded 'C:\Windows\System32\rpcrt4.dll'. Cannot find or open the PDB file.
'Hello World (ASM).exe' (Win32): Loaded 'C:\Program Files\NVIDIA Corporation\coprocmanager\detoured.dll'. Cannot find or open the PDB file.
'Hello World (ASM).exe' (Win32): Loaded 'C:\Program Files\NVIDIA Corporation\coprocmanager\Nvd3d9wrapx.dll'. Cannot find or open the PDB file.
'Hello World (ASM).exe' (Win32): Loaded 'C:\Windows\System32\setupapi.dll'. Cannot find or open the PDB file.
'Hello World (ASM).exe' (Win32): Loaded 'C:\Windows\System32\cfgmgr32.dll'. Cannot find or open the PDB file.
'Hello World (ASM).exe' (Win32): Loaded 'C:\Windows\System32\devobj.dll'. Cannot find or open the PDB file.
'Hello World (ASM).exe' (Win32): Loaded 'C:\Program Files\NVIDIA Corporation\coprocmanager\nvdxgiwrapx.dll'. Cannot find or open the PDB file.
'Hello World (ASM).exe' (Win32): Loaded 'C:\PROGRA~1\NVIDIA~1\NVSTRE~1\rxinput.dll'. Module was built without symbols.
'Hello World (ASM).exe' (Win32): Loaded 'C:\Windows\System32\ole32.dll'. Cannot find or open the PDB file.
'Hello World (ASM).exe' (Win32): Loaded 'C:\Windows\System32\oleaut32.dll'. Cannot find or open the PDB file.
'Hello World (ASM).exe' (Win32): Loaded 'C:\Windows\System32\combase.dll'. Cannot find or open the PDB file.
'Hello World (ASM).exe' (Win32): Unloaded 'C:\PROGRA~1\NVIDIA~1\NVSTRE~1\rxinput.dll'
'Hello World (ASM).exe' (Win32): Unloaded 'C:\Windows\System32\combase.dll'
'Hello World (ASM).exe' (Win32): Unloaded 'C:\Windows\System32\oleaut32.dll'
'Hello World (ASM).exe' (Win32): Unloaded 'C:\Windows\System32\ole32.dll'
First-chance exception at 0x000007FA9A09B9FB (gdi32.dll) in Hello World (ASM).exe: 0xC0000005: Access violation reading location 0xFFFFFFFFFFFFFFFF.
Unhandled exception at 0x000007FA9A09B9FB (gdi32.dll) in Hello World (ASM).exe: 0xC0000005: Access violation reading location 0xFFFFFFFFFFFFFFFF.
First-chance exception at 0x000007FA9A09B9FB (gdi32.dll) in Hello World (ASM).exe: 0xC0000005: Access violation reading location 0xFFFFFFFFFFFFFFFF.
Unhandled exception at 0x000007FA9A09B9FB (gdi32.dll) in Hello World (ASM).exe: 0xC0000005: Access violation reading location 0xFFFFFFFFFFFFFFFF.
First-chance exception at 0x000007FA9A09B9FB (gdi32.dll) in Hello World (ASM).exe: 0xC0000005: Access violation reading location 0xFFFFFFFFFFFFFFFF.
Unhandled exception at 0x000007FA9A09B9FB (gdi32.dll) in Hello World (ASM).exe: 0xC0000005: Access violation reading location 0xFFFFFFFFFFFFFFFF.
The program '[1080] Hello World (ASM).exe' has exited with code 0 (0x0).
4

1 に答える 1

4

WinAPI 関数を呼び出す前に、スタックにスペースを確保する必要があります。

sub rsp,40

Windows の x64 コードで他の関数を呼び出す場合、その関数にシャドウ/スピル/ホーム スペースを提供する必要があります。これは、最初の 4 つのパラメーターを渡すために使用される 4 つのレジスタをスピルできる領域です ( ECX, EDX, R8, R9)。4 つのクワッドワードは 32 バイトになります (呼び出す関数が 4 つ未満の引数を取る場合でも、常に 32 バイトです)。

では、なぜ 32 ではなく 40 を引くのでしょうか? スタックの配置に関する要件もあります。関数を呼び出す前に、スタック ポインターを 16 バイトの倍数に揃える必要があります (関数に入るとRIP、スタック上にもありますRSP % 16 == 8)。したがって、余分な 8 バイトの減算は、プログラムの開始時にスタック ポインターが 8 モジュロ 16 だったためです。いつもそうですか?わかりませんが、プログラムのエントリポイント (OS またはランタイム ライブラリ) を呼び出した人がcall.

代わりにsub rsp,40次を使用できます。

and esp,0xFFFFFFF0   ; align
sub rsp,32           ; allocate shadow space 
于 2013-08-08T06:26:27.300 に答える