質問: int main() { int i; for (i=0; i<10; i++) { printf("Hello, World!\n"); } return 0; } コマンド gcc version 5.3.1 20160413 (Ubuntu 5.3.1-14ubuntu2) $ gcc -o firstprog firstprog.c $ objdump -D firstprog | grep -A70 main.: 0804840b : 1 804840b: 8d 4c 24 04 lea 0x4(%esp),%ecx 2 804840f: 83 e4 f0 and $0xfffffff0,%esp #なぜこれをしないといけないのか? 3 8048412: ff 71 fc pushl -0x4(%ecx) ##これと対になるのはなにか? 4 8048415: 55 push %ebp 5 8048416: 89 e5 mov %esp,%ebp 6 8048418: 51 push %ecx ##これと対になるのはなにか? 7 8048419: 83 ec 14 sub $0x14,%esp ##なぜ10行目があるのに、これをしないといけないのか? 8 804841c: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) 9 8048423: eb 14 jmp 8048439 10 8048425: 83 ec 0c sub $0xc,%esp 11 8048428: 68 d0 84 04 08 push $0x80484d0 12 804842d: e8 ae fe ff ff call 80482e0 13 8048432: 83 c4 10 add $0x10,%esp 14 8048435: 83 45 f4 01 addl $0x1,-0xc(%ebp) 15 8048439: 83 7d f4 09 cmpl $0x9,-0xc(%ebp) 16 804843d: 7e e6 jle 8048425 17 804843f: b8 00 00 00 00 mov $0x0,%eax ##これはなにをしてるのか? 18 8048444: 8b 4d fc mov -0x4(%ebp),%ecx##これはなにをしてるのか? 19 8048447: c9 leave 20 8048448: 8d 61 fc lea -0x4(%ecx),%esp 21 804844b: c3 ret
回答: こんにちは。 全部は分からないので、解る部分だけ回答してみます。 > > 2 804840f: 83 e4 f0 and $0xfffffff0,%esp #なぜこれをしないといけないのか? > > > ローカル変数のアライメントを調整してローカル変数アクセス速度を最適化することが目的です。 自作エミュレータで学ぶx86アーキテクチャ: コンピュータが動く仕組みを徹底理解!の立ち読みできる部分にも解説がありました。(この本、解りやすそうな感じがします。) > > 7 8048419: 83 ec 14 sub $0x14,%esp ##なぜ10行目があるのに、これをしないといけないのか? > > > main()関数の一番外側のブロックで有効なローカル変数領域の確保ではないかと思います。 そして、恐らくfor()ループがあるのではないでしょうか? 10行目はそのforループ内で確保しているローカル変数領域の確保ではないかと思います。 > > 6 8048418: 51 push %ecx ##これと対になるのはなにか? > > > この直前で`mov %esp,%ebp`しているので、6行目終了時、ebp-4のアドレスにecxが記録されています。下記にてecxを回復しているのだと思います。 > > 18 8048444: 8b 4d fc mov -0x4(%ebp),%ecx##これはなにをしてるのか? > > > 17 804843f: b8 00 00 00 00 mov $0x0,%eax ##これはなにをしてるのか? > > > `return 0;`の0を設定しているのではないかと思います。 関数の戻り値を返却する際にeaxを使うことは良くあります。 80x86系のアセンブラは大昔に少し触っただけなので外していたらごめんなさい。