最近のgccはインラインアセンブラ内からcのgotoラベルに飛べる仕組みがあるのでそれのメモです。
ドキュメントはUsing the GNU Compiler Collection (GCC): Extended AsmとUsing the GNU Compiler Collection (GCC): Extended Asmです。たしかLKMLに送られてたpatchにもこれを使ったコードがあった気がします。
それはさておき、gotoを使う場合の書式は以下のようになっていて、asm gotoという形式です。
asm [volatile] goto ( AssemblerTemplate : : InputOperands : Clobbers : GotoLabels)
ドキュメントには-ansiオプションを付けてコンパイルする場合はasmではなくてasmを使うようにと書かれています。また、出力のオペランドは指定できないようです。そのため、計算の途中経過を保持したいときとかはClobbersのところでメモリに書き出すようにするみたいです。
以下が簡単なサンプルです。argcの数が3かどうか調べて3だったらsameラベルにジャンプしてます。
#include <stdio.h> int main(int argc, char **argv) { __asm__ goto("cmpl $0x3, %[argc]\n\t" "je %l[same]\n\t" : : [argc] "r"(argc) : :same); printf("argc is %d\n", argc); return 0; same: printf("argc == 3\n"); return 0; }
機械語になるとこんな感じです。
0000000000400527 <main>: 400527: 55 push %rbp 400528: 48 89 e5 mov %rsp,%rbp 40052b: 48 83 ec 10 sub $0x10,%rsp 40052f: 89 7d fc mov %edi,-0x4(%rbp) 400532: 48 89 75 f0 mov %rsi,-0x10(%rbp) 400536: 8b 45 fc mov -0x4(%rbp),%eax 400539: 83 f8 03 cmp $0x3,%eax 40053c: 74 1b je 400559 <main+0x32> 40053e: 8b 45 fc mov -0x4(%rbp),%eax 400541: 89 c6 mov %eax,%esi 400543: bf 00 06 40 00 mov $0x400600,%edi 400548: b8 00 00 00 00 mov $0x0,%eax 40054d: e8 ee fe ff ff callq 400440 <printf@plt> 400552: b8 00 00 00 00 mov $0x0,%eax 400557: eb 0f jmp 400568 <main+0x41> 400559: bf 0c 06 40 00 mov $0x40060c,%edi 40055e: e8 cd fe ff ff callq 400430 <puts@plt> 400563: b8 00 00 00 00 mov $0x0,%eax 400568: c9 leaveq 400569: c3 retq 40056a: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1)
- 作者: IgorZhirkov
- 出版社/メーカー: 翔泳社
- 発売日: 2018/01/19
- メディア: Kindle版
- この商品を含むブログを見る