アセンブラでエンディアン変換(その3)


アニメ『ゴブリンスレイヤー』

1話で冒険者であることのマイナス面を見せられ、魅了されました。ゴブリンからの、駆け出し冒険者たちへの、仕打ちが……、もう、本当に、ひどい。
とにかく、許せませんね、ゴブリン。
いきなりゴブリンへの負の感情がマックスになったので、ゴブリンスレイヤーが、どれだけゴブリンにひどいことをしても、スカッとするだけで、可哀想なんて微塵も感じませんでした。
ゴブリンに情けをかけないゴブリンスレイヤーから、ゴブリンへの憎しみも伝わってきて、ゴブリンは全滅すればいい、そんな気持ちしか沸いてきません。
今期始まったアニメで、ゴブリンを助けるアニメもありますが、こちらのアニメのおかげで、私は今、この世のすべてのゴブリンが信用できません。まあ、現実にはゴブリンは居ませんが。(ゴブリンみたいな奴はいますが)

アセンブラでエンディアン変換の続きです。

前回、htonlのソースを探している時に、.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$

.Sはアセンブラのソースなので、htonlのアセンブラを知りたければ、直接こちらを確認した方が早いです。
見てみましょう。

takk@deb9:~/src/glibc-2.24$ cat -n sysdeps/i386/htonl.S
     1  /* Change byte order in word.  For Intel 80x86, x >= 4.
     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 (htonl)
    29          movl    4(%esp), %eax
    30          bswap   %eax
    31          ret
    32  END (htonl)
    33
    34  weak_alias (htonl, ntohl)
takk@deb9:~/src/glibc-2.24$

実に簡単なコードです。
ENTRYというキーワードの引数にhtonlが指定されています。
CPUによって異なる命令・疑似命令を吸収してるっぽいですね。なかなか勉強になります。
他のCPUのアセンブラも見てみたくなりました。
ItaniumのアーキテクチャであるIA64のアセンブラのhtonlを見てみます。

takk@deb9:~/src/glibc-2.24$ cat -n sysdeps/ia64/htonl.S
     1  /* Change byte order in 32-bit value.  ia64 version.
     2     Copyright (C) 2000-2016 Free Software Foundation, Inc.
     3     This file is part of the GNU C Library.
     4     Contributed by Dan Pop <Dan.Pop@cern.ch>
     5
     6     The GNU C Library is free software; you can redistribute it and/or
     7     modify it under the terms of the GNU Lesser General Public
     8     License as published by the Free Software Foundation; either
     9     version 2.1 of the License, or (at your option) any later version.
    10
    11     The GNU C Library is distributed in the hope that it will be useful,
    12     but WITHOUT ANY WARRANTY; without even the implied warranty of
    13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    14     Lesser General Public License for more details.
    15
    16     You should have received a copy of the GNU Lesser General Public
    17     License along with the GNU C Library; if not, see
    18     <http://www.gnu.org/licenses/>.  */
    19
    20
    21  #include <sysdep.h>
    22
    23  ENTRY(htonl)
    24          shl     ret0 = r32, 32
    25          ;;
    26          mux1    ret0 = ret0, @rev
    27          ret
    28  END(htonl)
    29
    30  weak_alias (htonl, ntohl)
takk@deb9:~/src/glibc-2.24$

衝撃です。
パッと見。よく分かりません。どうしてこれでhtonlできるのでしょうか。
でもglibcのソースなので、これでhtonlできているはずです。
よく見てみます。
revというキーワードがあります。レビジョンの意味で突然出てくるわけがないので、リバースでしょう。ということは、mux1は、muがマルチ1が1バイト xがクロス……置換の意味でしょうか。
つまりmux1が置換命令で、@revで逆順にしていて、1行のアセンブラコードで1発エンディアン変換してくれている、ということでしょうね。
なかなかわくわくするアセンブリです。
itaniumも使ってみたいですねえ。

Leave a Reply

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

CAPTCHA