0

最初の 4 つの引数がレジスタ ( RCXRDXR8R9) にあり、追加の引数がスタックにプッシュされることはわかっています。

質問:

引数をスタックにプッシュする方法は? (push 0) で試してみましたが、うまくいきませんか?

コード( MASM64 )

extrn ExitProcess: PROC   
extrn MessageBoxExA: PROC
.data
caption db '64-bit hello!', 0
message db 'Hello World!', 0
.code
Start PROC
  sub    rsp, 38h        
  mov    rcx, 0         ; hWnd = HWND_DESKTOP
  lea    rdx, message   ; LPCSTR lpText
  lea    r8,  caption   ; LPCSTR lpCaption
  mov    r9d, 0         ; uType = MB_OK

  push   0          ; wLanguageId

  call   MessageBoxExA  
  mov    ecx, eax       
  add    rsp, 38h
  call ExitProcess
Start ENDP
End

私はそれを知ってMessageBoxおり、同じように動作しますが、(学習目的で) 1 つのパラメーターを渡す必要があるため、MessageBoxEx使用しようとしています。MessageBoxEx

私は同様の質問をしたことを知っていますが、これはそうではありませんが、vb.net に関連しています。

4

2 に答える 2

0

引数が渡される順序と、それらがレジスタで渡されるかスタックで渡されるか (呼び出し元または呼び出し先がクリーンアップを担当するかどうかと共に) は、「呼び出し規約」によって定義されます。

おそらく考えているのは STDCALL または CDECL です。どちらも 32 ビット Windows で使用される呼び出し規則であり、スタック上の引数を逆順 (右から左) に渡します。x64 は FastCall 呼び出し規則に移行しました。この場合、引数は順方向 (左から右) に渡され、最初の 4 つの引数はレジスタ RCX、RDX、R8、R9 で渡されます。4 を超える引数は、同じ左から右の順序でスタックに渡されます。元のポスターには、MASM を使用した x64 アセンブリ用の正しい呼び出し規約が設定されていました。また、RSP から減算されたシャドウ スペースの値は 20h (32d) である必要があると述べた上記の回答者は正しいです。シャドウ スペースは、FastCall のレジスタによって渡される 4 つの引数用のスタック上のスペースを許可しています。

上記のコードを次のように変更します。

extrn ExitProcess: PROC   
extrn MessageBoxExA: PROC
.data
caption db '64-bit hello!', 0
message db 'Hello World!', 0
.code

Start PROC
  sub    rsp, 20h        
  mov    rcx, 0         ; hWnd = HWND_DESKTOP
  lea    rdx, message   ; LPCSTR lpText
  lea    r8,  caption   ; LPCSTR lpCaption
  mov    r9d, 0         ; uType = MB_OK

  push   0          ; wLanguageId

  call   MessageBoxExA  
  mov    ecx, eax       
  add    rsp, 20h
  call ExitProcess
Start ENDP
End

64 ビット マシンの Visual Studio で問題なく動作する

于 2014-11-11T06:17:13.007 に答える