Category Archives: 7-1.ファイル・アーカイブ

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


アニメ『ユリシーズ ジャンヌ・ダルクと錬金の騎士』

ん~何というか、まだよく分かりません。ながら見しているので、ますます分かりません。でも見どころが「ベーゼ」であることは確かでしょう。

続きです。
16bitのエンディアン変換がアセンブラで作れなかったので、glibcのソース読んでみます。
hton*.Sのソースを検索。

takk@deb9:~/src/glibc-2.24$ find -name hton*
./sysdeps/ia64/htonl.S
./sysdeps/ia64/htons.S
./sysdeps/alpha/htonl.S
./sysdeps/alpha/htons.S
./sysdeps/i386/htonl.S
./sysdeps/i386/htons.S
./sysdeps/x86_64/htonl.S
./inet/htons.c
./inet/htontest.c
./inet/htonl.c
takk@deb9:~/src/glibc-2.24$

htonls.Sが16bitです。
全文確認してみます。

takk@deb9:~/src/glibc-2.24$ cat -n ./sysdeps/i386/htons.S
     1  /* Change byte order in word.  For Intel 80x86, x >= 3.
     2     Copyright (C) 1997-2016 Free Software Foundation, Inc.
     3     This file is part of the GNU C Library.
     4
     5     The GNU C Library is free software; you can redistribute it and/or
     6     modify it under the terms of the GNU Lesser General Public
     7     License as published by the Free Software Foundation; either
     8     version 2.1 of the License, or (at your option) any later version.
     9
    10     The GNU C Library is distributed in the hope that it will be useful,
    11     but WITHOUT ANY WARRANTY; without even the implied warranty of
    12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    13     Lesser General Public License for more details.
    14
    15     You should have received a copy of the GNU Lesser General Public
    16     License along with the GNU C Library; if not, see
    17     <http://www.gnu.org/licenses/>.  */
    18
    19  #include <sysdep.h>
    20  #include "asm-syntax.h"
    21
    22  /*
    23     INPUT PARAMETERS:
    24     word         (sp + 4)
    25  */
    26
    27          .text
    28  ENTRY (htons)
    29          movl    4(%esp), %eax
    30          andl    $0xffff, %eax
    31          rorw    $8, %ax
    32          ret
    33  END (htons)
    34
    35  weak_alias (htons, ntohs)
takk@deb9:~/src/glibc-2.24$

16bitの場合、bswap命令はないんですね。rorw $8, %xが、上下入れ替えの命令っぽいです。8の単位はbitですので、rorw命令は、bitローテートをしてくれる命令に違いありません。

では、my-bswap.sに16bitのエンディアン変換も加えてみます。

takk@deb9:~/tmp$ cat -n my-bswap.s
     1          .text
     2          .globl my_bswap_64
     3  my_bswap_64:
     4          mov %rdi, %rax
     5          bswap %rax
     6          ret
     7
     8          .globl my_bswap_32
     9  my_bswap_32:
    10          mov %rdi, %rax
    11          bswap %eax
    12          ret
    13
    14          .globl my_bswap_16
    15  my_bswap_16:
    16          mov %rdi, %rax
    17          andl $0xffff, %eax
    18          rorw $8, %ax
    19          ret
    20
takk@deb9:~/tmp$

アセンブル。

takk@deb9:~/tmp$ as -o my-bswap.o my-bswap.s
takk@deb9:~/tmp$ 

エラー出ませんでした。文法的に問題ないようです。

では、ライブラリ化します。

takk@deb9:~/tmp$ ar -rc libmybswap.a my-bswap.o
takk@deb9:~/tmp$

エンディアン変換ライブラリ、libmybswap.aが出来上がりました。

確認用に、main関数に、16bitのエンディアン変換の呼び出し処理を追加して、

takk@deb9:~/tmp$ cat -n main.c
     1  #include <stdio.h>
     2  #include <stdint.h>
     3  uint64_t my_bswap_64(uint64_t);
     4  uint32_t my_bswap_32(uint32_t);
     5  uint16_t my_bswap_16(uint16_t);
     6  int main()
     7  {
     8          uint64_t a=0x11223344aabbccdd;
     9          uint32_t b=0x12345678;
    10          uint16_t c=0x1234;
    11          a = my_bswap_64(a);
    12          printf("%16llx\n",a);
    13          b = my_bswap_32(b);
    14          printf("%08x\n",b);
    15          c = my_bswap_16(c);
    16          printf("%04x\n",c);
    17  }
takk@deb9:~/tmp$

ビルド、実行。

takk@deb9:~/tmp$ gcc main.c -L. -lmybswap
takk@deb9:~/tmp$
takk@deb9:~/tmp$ ./a.out
ddccbbaa44332211
78563412
3412
takk@deb9:~/tmp$

もう何でも作れそうな気がしてきました。