3

Mac OS X の x86_64 でコマンド ライン引数を取得するには、次のようにします。

_main:
  sub   rsp, 8         ; 16 bit stack alignment
  mov   rax, 0
  mov   rdi, format
  mov   rsi, [rsp + 32]
  call  _printf

フォーマットは「%s」です。rsi は argv[0] に設定されます。

したがって、これから、スタックが最初にどのように見えるか(私が思うに)を引き出しました。

 top of stack
               <- rsp after alignment
return address <- rsp at beginning (aligned rsp + 8)
  [something]  <- rsp + 16
    argc       <- rsp + 24
   argv[0]     <- rsp + 32
   argv[1]     <- rsp + 40
    ...            ...
bottom of stack

等々。読みづらかったらすいません。【何か】が気になる。いくつかのテストの後、通常は 0 であることがわかりました。ただし、(一見) 乱数である場合もあります。

また、残りのスタックの描画が正しいかどうか教えていただけますか?

4

2 に答える 2

2

AMD64 ABI (3.2.3、パラメーターの受け渡し) によると、パラメーターは INTEGER クラスであるため、 (左から右の順序で) &main(int argc, char **argv)に渡されます。が使用された場合は、 などに渡されます。 次のようにそれらを現在のフレームに配置します(おそらく便宜上?レジスタを解放しますか?):rdirsienvprdxgcc

mov    DWORD PTR [rbp-0x4],  edi
mov    QWORD PTR [rbp-0x10], rsi

フレームポインタが省略された場合、アドレッシングは を基準にしrspます。通常、argv1 8 バイト下になりますrbp(argc必須ではありませんが、最初に来ます)。したがって、次のようになります。

# after prologue
mov    rax, QWORD PTR [rbp-0x10] # or you could grab it from rsi, etc.
add    rax, 0x8
mov    rsi, QWORD PTR [rax]
mov    edi, 0x40064c # format
call   400418 <printf@plt>
于 2012-04-04T07:47:08.407 に答える
1

あなたはそれを近くに持っています。

argv配列がどこにあるかではなく、配列ポインタです。Cと書かれているので、char **argv文字列に到達するには 2 レベルの逆参照を行う必要があります。

 top of stack
               <- rsp after alignment
return address <- rsp at beginning (aligned rsp + 8)
  [something]  <- rsp + 16
    argc       <- rsp + 24
   argv        <- rsp + 32
   envp        <- rsp + 40  (in most Unix-compatible systems, the environment
    ...            ...       string array, char **envp)
bottom of stack
 ...
somewhere else:
   argv[0]     <- argv+0:   address of first parameter (program path or name)
   argv[1]     <- argv+8:   address of second parameter (first command line argument)
   argv[2]     <- argv+16:  address of third parameter (second command line argument)
    ...
   argv[argc]  <-  argv+argc*8:  NULL
于 2012-04-04T05:26:26.300 に答える