読者です 読者をやめる 読者になる 読者になる

ゆとりーなの日記

日記的な事を書いて行くと思はれる

int main(void)だけどコマンドライン引數餘裕でした

C言語のmain函數は特殊です。引數を取らないパターン(int main(void))、コマンドライン引數を取るパターン(int main(int argc, char **argv)等)を書くことが出來ます。
今回はint main(void)のパターンでもmainを呼ぶ側はきつとコマンドライン引數をレジスタに入れてからmain函數を呼び出してゐるだらうと一點讀みをすることでint main(void)と言ひつつコマンドライン引數を取得してみるといふ暴擧に出てみることにします。
私の環境はx86_64のgccですので、第一引數はrdi、第二引數はrsiレジスタに入つてゐると假定出來ます。といふわけでlea命令を使つてargc、argvにそれぞれコマンドライン引數の數、文字列の配列を突つ込んでみます。

#include <stdio.h>

int main(void) {
  int argc;
  char **argv;
  int i;
  __asm__ volatile ("leal (%%rdi), %0" : "=r"(argc));
  __asm__ volatile ("leaq (%%rsi), %0" : "=r"(argv));
  printf("argc=%d\n", argc);
  for (i = 0; i < argc; ++i) {
    printf("%s\n", argv[i]);
  }
  return 0;
}

以下結果です。
入力1

./a.out

出力1

argc=1
./a.out

入力2

./a.out hoge fuga hage

出力2

argc=4
./a.out
hoge
fuga
hage

あつさり取得できました。
まあ正直メモリアドレスつて感じではなかつたのでleaよりもmovな感じはする?のですが何故かrdiやrsiにはmov使へないのでかうなりました(と思つてゐたのですがrsiには使へました)。