アセンブラのライブラリ(その3)


アニメ『からくりサーカス』

すごいからくり人形です。操る糸が弱点のような気もします。絡まないのでしょうか。

こねくり回して絡まってきたアセンブラの続きです。
前回関数をアセンブラ化しましたが、少し寝かせてみると、なんだか冗長な気がしてきました。

takk@deb9:~/tmp$ cat -n my_htonl-asm.s
     1          .text
     2          .globl my_htonl
     3  my_htonl:
     4          pushq %rbp
     5          movq %rsp, %rbp
     6          mov %rdi, %rax
     7          bswap %eax
     8          popq %rbp
     9          ret
    10
takk@deb9:~/tmp$

最初にpush/popの枠から作成したため残ってしまいましたが、push/popの必要性を感じません。
push/popをカットしてみます。

takk@deb9:~/tmp$ cat -n my_htonl-asm.s
     1          .text
     2          .globl my_htonl
     3  my_htonl:
     4          mov %rdi, %rax
     5          bswap %eax
     6          ret
     7
takk@deb9:~/tmp$

できました。
glibcのhtonl.Sのソースにそっくりです。

実行してみます。

takk@deb9:~/tmp$ as -o my_htonl.o my_htonl-asm.s
takk@deb9:~/tmp$ gcc main.c my_htonl.o
takk@deb9:~/tmp$ ./a.out
78563412
takk@deb9:~/tmp$ 

動いていそうです。
でも、push/popをしていないソースって、少し心配になります。
関数でラッピングしてみます。

変更前。

takk@deb9:~/tmp$ cat -n main.c
     1  #include <stdio.h>
     2  unsigned long my_htonl(unsigned long);
     3  int main()
     4  {
     5          unsigned long a=0x12345678;
     6          a = my_htonl(a);
     7          printf("%08x\n",a);
     8  }
takk@deb9:~/tmp$

変更後。

takk@deb9:~/tmp$ cat -n main.c
     1  #include <stdio.h>
     2  unsigned long my_htonl(unsigned long);
     3  unsigned long func1(unsigned long a)
     4  {
     5          return my_htonl(a);
     6  }
     7  int main()
     8  {
     9          unsigned long a=0x12345678;
    10          a = func1(a);
    11          printf("%08x\n",a);
    12  }
takk@deb9:~/tmp$

ビルド、実行。

takk@deb9:~/tmp$ gcc main.c my_htonl.o
takk@deb9:~/tmp$ ./a.out
78563412
takk@deb9:~/tmp$

結果は合ってますね。

では、アセンブラを見て確認。

00000000000006b0 <func1>:
 6b0:   55                      push   %rbp
 6b1:   48 89 e5                mov    %rsp,%rbp
 6b4:   48 83 ec 10             sub    $0x10,%rsp
 6b8:   48 89 7d f8             mov    %rdi,-0x8(%rbp)
 6bc:   48 8b 45 f8             mov    -0x8(%rbp),%rax
 6c0:   48 89 c7                mov    %rax,%rdi
 6c3:   e8 41 00 00 00          callq  709 <my_htonl>
 6c8:   c9                      leaveq
 6c9:   c3                      retq

00000000000006ca <main>:
 6ca:   55                      push   %rbp
 6cb:   48 89 e5                mov    %rsp,%rbp
 6ce:   48 83 ec 10             sub    $0x10,%rsp
 6d2:   48 c7 45 f8 78 56 34    movq   $0x12345678,-0x8(%rbp)
 6d9:   12
 6da:   48 8b 45 f8             mov    -0x8(%rbp),%rax
 6de:   48 89 c7                mov    %rax,%rdi
 6e1:   e8 ca ff ff ff          callq  6b0 <func1>
 6e6:   48 89 45 f8             mov    %rax,-0x8(%rbp)
 6ea:   48 8b 45 f8             mov    -0x8(%rbp),%rax
 6ee:   48 89 c6                mov    %rax,%rsi
 6f1:   48 8d 3d 9c 00 00 00    lea    0x9c(%rip),%rdi        # 794 <_IO_stdin_used+0x4>
 6f8:   b8 00 00 00 00          mov    $0x0,%eax
 6fd:   e8 5e fe ff ff          callq  560 <printf@plt>
 702:   b8 00 00 00 00          mov    $0x0,%eax
 707:   c9                      leaveq
 708:   c3                      retq

0000000000000709 <my_htonl>:
 709:   48 89 f8                mov    %rdi,%rax
 70c:   0f c8                   bswap  %eax
 70e:   c3                      retq
 70f:   90                      nop

func1からmy_htonlの呼び出し時に、raxをrdiにコピーしています。
my_htonlでは、そのrdiをraxにコピーして使うだけなので、問題なさそうです。

Leave a Reply

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

CAPTCHA