ここから本文です

アセンブリ言語について質問です。

アバター

ID非公開さん

2017/12/2523:38:39

アセンブリ言語について質問です。

現在大学一年生でプログラミングの授業でアセンブリ言語を学んでいます。

以下のC言語のソースコードのアセンブリ言語について分からないところがあるので教えて下さい。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
char buffer[256];
strcpy(buffer, argv[1]);
printf("%s\n", buffer);
return 0;
}



アセンブリ言語
push rbp
mov rsp, rbp
sub rsp, 0x110
mov DWORD PTR[rbp - 0x104], edi
mov QWORD PTR[rbp - 0x110], rsi
mov rax, QWORD PTR[rbp - 0x110]
add rax, 0x8
mov rdx, QWORD PTR[rax]
lea rax, [rbp - 0x100]
mov rsi, rdx
mov rdi, rax
call 0x400430 <strcpy@plt>
mov rax, QWORD PTR[rbp - 0x110]
add rax, 0x8
mov rax, QWORD PTR[rax]
mov rdi, rax
call 0x400440 <puts@plt>
mov eax, 0x0
leave
ret



C言語をgccでコンパイルし、./a.out helloを実行しました。

とあるサイトでレジスタrdi, rsi, rdxはそれぞれ第1引数、第2引数、第3引数が入るとあって、argc=2はrdx,たargv[0]=./a.outはrsi,argv[1]=helloはrdxに入っていると思ってました。



第一引数であるargc = 2はediに直接入っていましたが、第2引数と第3引数はそれぞれrsi,rdxには直接入っておらず、別のメモリアドレスに確保された第2引数、第3引数のメモリアドレスがそれぞれrsi,rdxに入っていました。


なぜ、第一引数と同様に第2引数、第3引数は直接rsi,rdxに入らないのですか?


色々とこんがらがって、よく分からなくなったので質問させて頂きました。

回答お願いします。

閲覧数:
158
回答数:
3
お礼:
50枚

違反報告

ベストアンサーに選ばれた回答

oss********さん

2017/12/2609:31:26

文字列そのものではなく、その文字列に対してのポインタが引数となります。
自分の書いたmain関数をよーく見てもらうとわかると思うけど、 argc は int だけど、argv[] は char * と書いてるでしょ?
そのまんまですよ。
レジスタに可変の文字列そのものが入るわけないというのは直感的に理解できると思いますが、だから文字列のポインタが引数になってるんです。
これはCの言語仕様なんで『何故?』という疑問をはさむ余地はないです。
そういう仕様なんだと理解してください。

  • アバター

    質問者

    ID非公開さん

    2017/12/2815:26:15

    回答ありがとうございます。
    理解することができました。

    もうひとつ別に質問があるのですが、strcpy()呼び出しのcall命令についてです。

    mainの中の関数の呼び出しでのcall命令はリターンアドレスとrbpをプッシュし新たなスタックフレームが作成されると思ったのですがメモリ内容を確認してみるとrbpの値は変わらず、rspのみが変化していました。

    strcpy()呼び出して実行しているときのリターンアドレスや新たなrbpはなぜプッシュされないのでしょうか?

    どういう仕組みでstrcpyが実行されているのかがよく分かりません。お願いします。

  • その他の返信(1件)を表示

返信を取り消しますが
よろしいですか?

  • 取り消す
  • キャンセル

この回答は投票によってベストアンサーに選ばれました!

ベストアンサー以外の回答

1〜2件/2件中

並び替え:回答日時の
新しい順
|古い順

ilo********さん

2017/12/2605:06:24

char *argv[] は「"文字列の先頭アドレス"の配列」の先頭アドレスです。

./a.out hello を実行した場合、
文字列は "./a.out" と "hello" の2つです。
この2つの文字列の先頭アドレスを並べて格納した配列が argv[] です。
そして、その配列の先頭アドレスが argv に入ってきます。

返信を取り消しますが
よろしいですか?

  • 取り消す
  • キャンセル

kaz********さん

2017/12/2600:51:38

int main(int argc, char *argv[])
なので、
第1引数はint:edi
第2引数はchar*[]:rsi
になります。

返信を取り消しますが
よろしいですか?

  • 取り消す
  • キャンセル

あわせて知りたい

みんなで作る知恵袋 悩みや疑問、なんでも気軽にきいちゃおう!

Q&Aをキーワードで検索:

Yahoo! JAPANは、回答に記載された内容の信ぴょう性、正確性を保証しておりません。
お客様自身の責任と判断で、ご利用ください。
本文はここまでです このページの先頭へ

「追加する」ボタンを押してください。

閉じる

※知恵コレクションに追加された質問は選択されたID/ニックネームのMy知恵袋で確認できます。

不適切な投稿でないことを報告しました。

閉じる