コマンドライン引数

1. はじめに

プログラムを実行する際に受け取ったコマンドライン引数をどう受けとるかを説明します。

2. レジスタ/メモリ のイメージ

コマンドラインからの引数の数は、プログラム 起動時にレジスタ RDI に格納されてきます。
注意点は実行パス + 引数の数のため、3個引数を与えた場合には “4”が格納されています。
実際の値はRSIに格納されたアドレスに、更に格納されたアドレスのメモリに値が格納されています。
以下は、レジスタ、メモリ、実際の値が格納された状態のイメージ図です。

実行コマンドは以下の場合となります。

$sample_args2 hoge1 hoge2 hoge3

以下は、実際のコマンドライン引数が格納されたメモリの内容イメージです。

実行ファイルパスから0x00(NUL)を挟んで、引数1の値、引数2の値、引数3の値が順番に格納されています。

3. 実行確認

gdbを利用して実行を確認してみます。

$gdb sample_args2   

でデバッグ起動します。

(gdb)run hoge1 hoge2 hoge3

と実行することで、実行時にコマンドライン引数を渡したようにデバッグが実施できます。
実行後、すぐにレジスターの情報を確認します。
この時点で、レジスタ rdi と rsi に指定の値が格納されています。
レジスタ rsi に格納されたアドレスは、

0x7fffffffe038

に格納された値を確認すると、

0xa6 0xe3 0xff 0xff 0xff 0x7f 0x00 0x00

と言う並びで実際の値の『アドレス』が格納されています。

リトルエンディアンですので、実際には、

0x00 0x00 0x7f 0xff 0xff 0xff 0xe3 0xa6

と言う順番がアドレスになります。
そのアドレスを確認すると実行パスの最初のAsciiコードの”/“が保存されています。
次に rsi のアドレスに 8 を加算すると以下のアドレスとなります。

0x7fffffffe040

ここから先ほどと同様に値を確認する事ができます。
このように格納されたコマンドライン引数を利用して、ユーザーが指定した値を受け取ることができます。