C言語でx64アセンブラを覚える(その2)


アニメ『叛逆性ミリオンアーサー』

何が何だか。100万人のアーサーたちが持っているエクスカリバーを、アーサーたちが叩き折るというストーリーです。銃やバズーカのような剣ではない形のエクスカリバー、それを使うアーサーも男女ちびっ子いろんなアーサーがいます。ん~。聖剣エクスカリバーを抜いたっていうアーサー王が100万人いる、ってところで挫けました。発想は天才だなあと思います。でも天才に憧れるので、視聴は続けます。これもゲームが最初なんですね。どんなゲームなのか気になります。

ではアセンブラの続きです。
前回、if文をアセンブラで確認したので、今回は、for文を確認してみます。
ベースの空mainはそのままです。

takk@deb9:~/tmp$ cat -n t.c
     1  int main()
     2  {
     3
     4  }
takk@deb9:~/tmp$

for文で10回繰り返す処理を作ります。

takk@deb9:~/tmp$ cat -n t1.c
     1  int main()
     2  {
     3          int i;
     4          int a=50;
     5          for(i=0;i<10;i++)
     6                  a++;
     7  }
takk@deb9:~/tmp$

変数aを、10回+インクリメントする処理です。

アセンブル。どのようなアセンブラが生成されるでしょうか。

takk@deb9:~/tmp$ gcc -S t1.c
takk@deb9:~/tmp$ diff t.s t1.s
1c1
<       .file   "t.c"
---
>       .file   "t1.c"
12a13,21
>       movl    $50, -8(%rbp)
>       movl    $0, -4(%rbp)
>       jmp     .L2
> .L3:
>       addl    $1, -8(%rbp)
>       addl    $1, -4(%rbp)
> .L2:
>       cmpl    $9, -4(%rbp)
>       jle     .L3
takk@deb9:~/tmp$

変数aは、-8(%rbp)、変数iは、-4(%rbp)のようです。
aとiの初期化後、いきなり.L2へジャンプしてます。
比較から始めるんですね。
しかも、変数iの値tを10と比較するのではなく、9と比較しています。
変数aとiのインクリメントは、直接メモリに1加算してますね。

変数iをレジスタに変更してみます。C言語では、register指定子を付けるだけです。

takk@deb9:~/tmp$ cat -n t2.c
     1  int main()
     2  {
     3          register int i;
     4          int a=50;
     5          for(i=0;i<10;i++)
     6                  a++;
     7  }
takk@deb9:~/tmp$ gcc -S t2.c
takk@deb9:~/tmp$

アセンブラを見てみます。

takk@deb9:~/tmp$ diff t.s t2.s
1c1
<       .file   "t.c"
---
>       .file   "t2.c"
12a13,23
>       pushq   %rbx
>       .cfi_offset 3, -24
>       movl    $50, -12(%rbp)
>       movl    $0, %ebx
>       jmp     .L2
> .L3:
>       addl    $1, -12(%rbp)
>       addl    $1, %ebx
> .L2:
>       cmpl    $9, %ebx
>       jle     .L3
13a25
>       popq    %rbx
takk@deb9:~/tmp$

レジスタにしても、コードの行数は同じでした。

Leave a Reply

Your email address will not be published. Required fields are marked *

CAPTCHA