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


アニメ『青春ブタ野郎はバニーガール先輩の夢を見ない』

思春期症候群ってのにかかると、周囲の人から見えなくなったり、毎日過去に戻ったりします。まあ、その設定はそれではそれで面白いのですが、どうも主人公がよくわからない。登場する女子は魅力的なのですが、主人公にまったく魅力を感じません。大事な人が記憶から消えてしまうかもしれないのに、なんでしょう、無感情に見えてしまいます。ながら見が原因かもしれませんが。まあ、もう少し様子を見てみます。

前回突然ARMのアセンブラを見ましたが、やはり1つのCPUについて深く学習してから次を学んだ方がいい気がしてきましたので、またIntelに戻ります。

で、今回は、if文、switch文のアセンブラがどうなるかの確認です。

では、if文から。

takk@deb9:~/tmp$ cat -n t.c
     1  int main()
     2  {
     3          int a=10;
     4          int b;
     5          if(a == 10)
     6                  b = 100;
     7          else
     8                  b = 200;
     9  }
takk@deb9:~/tmp$

これのアセンブラは、こうなります。

takk@deb9:~/tmp$ cat -n t.s
     1          .file   "t.c"
     2          .text
     3          .globl  main
     4          .type   main, @function
     5  main:
     6  .LFB0:
     7          .cfi_startproc
     8          pushq   %rbp
     9          .cfi_def_cfa_offset 16
    10          .cfi_offset 6, -16
    11          movq    %rsp, %rbp
    12          .cfi_def_cfa_register 6
    13          movl    $10, -4(%rbp)
    14          cmpl    $10, -4(%rbp)
    15          jne     .L2
    16          movl    $100, -8(%rbp)
    17          jmp     .L3
    18  .L2:
    19          movl    $200, -8(%rbp)
    20  .L3:
    21          movl    $0, %eax
    22          popq    %rbp
    23          .cfi_def_cfa 7, 8
    24          ret
    25          .cfi_endproc
    26  .LFE0:
    27          .size   main, .-main
    28          .ident  "GCC: (Debian 6.3.0-18+deb9u1) 6.3.0 20170516"
    29          .section        .note.GNU-stack,"",@progbits
takk@deb9:~/tmp$

次は、else ifを追加しました。

takk@deb9:~/tmp$ cat -n t1.c
     1  int main()
     2  {
     3          int a=10;
     4          int b;
     5          if(a == 10)
     6                  b = 100;
     7          else if(a == 20)
     8                  b = 200;
     9          else
    10                  b = 300;
    11  }
takk@deb9:~/tmp$

else ifを追加したアセンブラとのコード差分です。

takk@deb9:~/tmp$ gcc -S t1.c
takk@deb9:~/tmp$ diff t.s t1.s
1c1
<       .file   "t.c"
---
>       .file   "t1.c"
18a19,20
>       cmpl    $20, -4(%rbp)
>       jne     .L4
19a22,24
>       jmp     .L3
> .L4:
>       movl    $300, -8(%rbp)
takk@deb9:~/tmp$

最後にswitch文。switchになっただけif文とやっていることは同じです。

takk@deb9:~/tmp$ cat -n t2.c
     1  int main()
     2  {
     3          int a=10;
     4          int b;
     5          switch(a){
     6          case    10:
     7                  b = 100;
     8                  break;
     9          case    20:
    10                  b = 200;
    11                  break;
    12          default:
    13                  b = 300;
    14          }
    15  }
takk@deb9:~/tmp$
takk@deb9:~/tmp$ gcc -S t2.c
takk@deb9:~/tmp$ diff t1.s t2.s
1c1
<       .file   "t1.c"
---
>       .file   "t2.c"
14,15c14,20
<       cmpl    $10, -4(%rbp)
<       jne     .L2
---
>       movl    -4(%rbp), %eax
>       cmpl    $10, %eax
>       je      .L3
>       cmpl    $20, %eax
>       je      .L4
>       jmp     .L7
> .L3:
17,22c22
<       jmp     .L3
< .L2:
<       cmpl    $20, -4(%rbp)
<       jne     .L4
<       movl    $200, -8(%rbp)
<       jmp     .L3
---
>       jmp     .L5
23a24,26
>       movl    $200, -8(%rbp)
>       jmp     .L5
> .L7:
25c28
< .L3:
---
> .L5:
takk@deb9:~/tmp$

comp $10と、comp $20。
それと、movl $200,・・・の行を見比べてみると、大差ありません。
ifでもswitchでもどっちでもアセンブラのコード量は変わらなってことですね。

Leave a Reply

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

CAPTCHA