主語を大きく取りすぎている可能性がある(実際に確認したのは「Mac の i386/x86_64 をターゲットとする、Xcode に含まれている Clang のインラインアセンブラ」だけ)のですが、記事タイトル通りのことになります。

Linux の i386/x86_64 や Windows の x86/x64 をターゲットとする場合は GCC (GAS) でも Clang でも .align.balign の意味、つまり引数はバイト数を指定します。一方、Mac の場合は .p2align の意味、つまり2を指定した数で累乗したバイト数でアライメントされます。なので、64 バイトアライメントにするつもりで .align 64 とかやると16エクサバイトアライメントと見なされてエラーになります。

例えば以下のプログラムを x86_64 向けにコンパイルするとします。

int main(void)
{
        int ret;
        asm volatile (
                ".align 4\n"
                "incl %%eax\n"
                ".align 4\n"
        : "=a"(ret));
        return ret;
}

Linux だと以下のようになります。

[umezawa@devcent7:pts/0 ~]$ clang -o asmalign asmalign.c
[umezawa@devcent7:pts/0 ~]$ gdb asmalign
GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-94.el7
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
...
Reading symbols from /home/umezawa/asmalign...(no debugging symbols found)...done.
(gdb) disassemble main
Dump of assembler code for function main:
   0x00000000004004f0 <+0>:     push   %rbp
   0x00000000004004f1 <+1>:     mov    %rsp,%rbp
   0x00000000004004f4 <+4>:     movl   $0x0,-0x4(%rbp)
   0x00000000004004fb <+11>:    nop
   0x00000000004004fc <+12>:    inc    %eax            # ここ
   0x00000000004004fe <+14>:    xchg   %ax,%ax
   0x0000000000400500 <+16>:    mov    %eax,-0x8(%rbp) # ここ
   0x0000000000400503 <+19>:    mov    -0x8(%rbp),%eax
   0x0000000000400506 <+22>:    pop    %rbp
   0x0000000000400507 <+23>:    retq
End of assembler dump.

Mac だと以下のようになります。

[umezawa@metis:ttys000 ~]$ clang -o asmalign asmalign.c
[umezawa@metis:ttys000 ~]$ lldb asmalign
(lldb) target create "asmalign"
Current executable set to 'asmalign' (x86_64).
(lldb) disassemble --name main
asmalign`main:
asmalign[0x100000f90] <+0>:  pushq  %rbp
asmalign[0x100000f91] <+1>:  movq   %rsp, %rbp
asmalign[0x100000f94] <+4>:  movl   $0x0, -0x4(%rbp)
asmalign[0x100000f9b] <+11>: nopl   (%rax,%rax)
asmalign[0x100000fa0] <+16>: incl   %eax             # ここ
asmalign[0x100000fa2] <+18>: nopw   %cs:(%rax,%rax)
asmalign[0x100000fb0] <+32>: movl   %eax, -0x8(%rbp) # ここ
asmalign[0x100000fb3] <+35>: movl   -0x8(%rbp), %eax
asmalign[0x100000fb6] <+38>: popq   %rbp
asmalign[0x100000fb7] <+39>: retq

私はバイト数指定で慣れているので .balign に置き換えればそれで済むことなんですが、なんでこんなことになってるんでしょう。 PowerPC 時代からの伝統でしょうか。

その2の続き

Intel 記法と Input Operand (の一部の制約)は併用できないわけですが、手持ちのソースを AT&T 記法に変換するのもチョー大変なので別の方法を。

Read the rest of this entry

同一 asm 句内に定義がある場合はいいのですが、別の asm 句に定義があると処理できません。

Read the rest of this entry

その1の続き

一つ重要なテストを忘れていました。 Extended Asm の Input Operand です。

Read the rest of this entry

Unix の ld コマンド(GNU の ld コマンド固有かもしれないけど)には --whole-archive というオプションがあって、スタティックライブラリの中のオブジェクトファイルを、どこからも参照されていなくても出力ファイルに含めることができます。これは、スタティックライブラリをシェアードライブラリに変換する手法としても知られています。

で、Visual C++ の場合に同様のことをやる方法ですが、バージョンによってちょっと違います。

Read the rest of this entry

性能向上
  • UQY2, UQRG, UQRA: エンコードを高速化した。

Read the rest of this entry

結論から言うと、インラインアセンブラ部分の先頭に .intel_syntax noprefix と書く(だけ)。 -masm=intel オプションは付けなくてもいいが、GCC との互換性を考えると付けるべき、となります。(Clang しか考えないなら付けなくてもいい)。

以下経過と詳細な挙動。環境は CentOS 7 + Clang 3.5.2 です。

Read the rest of this entry

GCC には -wrapper オプションというのがあり、サブプロセスを起動するときのラッパーを指定することができます。

Read the rest of this entry

GCC のインラインアセンブラは以下のような構文をしています。(https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html)

Read the rest of this entry

その6の続き

今までずっと x86 を試していましたが、 x64 ではどうでしょうか。

Read the rest of this entry