インラインアセンブラ 2013年10月20日


 

 

Cのなかに__asm__()とかでアセンブリ記述するアレがインラインアセンブラなわけですが、

とあるイケメンの人のやろうとしていたことを数人でやっていたのけれども

なかなかうまくいかなかったのでかいてみる。

 

アセンブリのコード

.intel_syntax noprefix
.text
.global main

main:
        xor eax,eax
        push eax
        push 0x64726c6f
        push 0x77206f6c
        push 0x6c656800
        mov ecx,esp
        mov eax,4
        mov ebx,1
        mov edx,14
        int 0x80

        mov eax,1
        dec ebx
        int 0x80

見ての通り、hello world という文字列を出力するアセンブリのコード。

これをインラインアセンブリで書いてみると、

int main(){
  __asm__(
          ".intel_syntax noprefix   nt"
          ".global func             nt"
          "func:                    nt"
          "xor eax,eax              nt"
          "push eax                 nt"
          "push 0x64726c6f          nt"
          "push 0x77206f6c          nt"
          "push 0x6c656800          nt"
          "mov ecx,esp              nt"
          "mov eax,4                nt"
          "mov ebx,1                nt"
          "mov edx,14               nt"
          "int 0x80                 nt"

          "mov eax,1                nt"
          "dec ebx                  nt"
          "int 0x80                 nt"
          );
  return 0;

}

まぁんで、普通にコンパイルするなら、

$ gcc hello.c -masm=intel

って指定するんだけど、

".intel_syntax noprefix   nt"

って記述してるわけだし、 -masm=intel つけなくてもコンパイルできるんじゃね?って話。

実際、-masm=intel を指定しない場合で、.intel_syntax noprefix と記述しているときには

$ gcc hello.c    
/tmp/ccOPOda9.s: Assembler messages:
/tmp/ccOPOda9.s:34: Error: no such instruction: `movl $0,%eax'
/tmp/ccOPOda9.s:35: Error: no such instruction: `popl %ebp'

記述されていない時には、

$ gcc hello.c      
hello.c: Assembler messages:
hello.c:4: Error: too many memory references for `xor'
hello.c:9: Error: too many memory references for `mov'
hello.c:10: Error: too many memory references for `mov'
hello.c:11: Error: too many memory references for `mov'
hello.c:12: Error: too many memory references for `mov'
hello.c:13: Error: operand size mismatch for `int'
hello.c:14: Error: too many memory references for `mov'
hello.c:15: Error: no instruction mnemonic suffix given and no register operands; can't size instruction
hello.c:16: Error: operand size mismatch for `int'

っていうように、明らかに .intel_syntax noprefix という記述は反映されてるっぽい。

コンパイルエラーみてると、なんか内部的に intel表記からAT&T表記に

コンバートしてる感もあるんだけど、これって、-masm=intel を付けないでも

どうにかすればコンパイルできる気はするんだけど、わからない。

 

だれか知っている人いれば教えていただけると嬉しいです。

 

gccの仕様でできないとかそういうのだったりするのかな….

追記:

こおしいず氏が解決してくれた。

gccでinline assemblyしたとき – cookies.txt               .scr http://cookies.hatenablog.jp/entry/2013/10/21/203345

gdbでbreakかければ/tmp/以下のファイル消える前に

見れると思ったけどunlinkにかけるべきだった。

技術力不足で辛い。

ありがとう!

Leave a Reply