2013-08-10 6 views
6

チュートリアルからこのプログラムをコンパイルできません。 "Hello World"が表示されます。 Linuxでこのプログラムをinline asmでコンパイルするには?

void main() 
{ 
    __asm__("jmp forward\n\t" 
"backward:\n\t" 
      "popl %esi\n\t" 
      "movl $4, %eax\n\t" 
      "movl $2, %ebx\n\t" 
      "movl %esi, %ecx\n\t" 
      "movl $12, %edx\n\t" 
      "int $0x80\n\t" 
      "int3\n\t" 
"forward:\n\t" 
      "call backward\n\t" 
      ".string \"Hello World\\n\"" 
      ); 
} 

gcc 4.7私に次のエラーを与える:

gcc hello.c -o hello 
hello.c: Assembler messages: 
hello.c:5: Error: invalid instruction suffix for `pop' 

また、各ラインの二重引用符を指定するには、回避する方法はありますか?

また、libcをサービスの代わりにprintfと呼び出すようにプログラムを変更する方法を知りたいと思います。

+0

だけでなく、それがいずれかの 'int型main'である必要があり、それは間違いなくあなたがに出力するx86-32コードをコンパイルしているように見え、あなたが – aaronman

+2

を使用しているコンピュータに応じて、クラッシュする可能性がありますので、ASMは依存きれいシステムであり、 x86-64バイナリ。 – Nayuki

+1

'l'sを削除し、'%e * 'を'%r * 'に変更することができます。これはどこかにあります。しかし、私の意見を信用しないでください。 – Ryan

答えて

9

Q

hello.c: Assembler messages: 
hello.c:5: Error: invalid instruction suffix for `pop' 

popl(それは代わりにpopqを持っている)x86-32上ではなく、x86-64で使用できます。 x86-64で動作するようにアセンブリコードを適合させるか、GCCを呼び出してx86-32バイナリ出力を生成する必要があります。

x86-32を生成すると仮定すると、コマンドラインオプション-m32を使用します。

Q

Is there also a way to avoid to specify double quotes for each line?

:いいえ。これは、__asm__()が文字列引数を取る擬似関数なので、文字列はCの構文に従うからです。文字列の内容は、ほとんどまたはまったく処理されずにアセンブラに渡されます。

文字列が並置されている場合、Cでは連結されています。たとえば、"a" "b""ab"と同じです。

アセンブリ言語構文(GAS)では、改行またはセミコロン(ステートメント)を次のように区切ることができます。"movl xxx; call yyy"または"movl xxx \n call yyy"

Q

how to modify the program to use libc call printf

calling convention for C on x86に従ってください。引数を右から左にプッシュし、関数を呼び出してスタックをクリーンアップします。例:

pushl $5678 /* Second number */ 
pushl $1234 /* First number */ 
pushl $fmtstr 
call printf 
addl $12, %esp /* Pop 3 arguments of 4 bytes each */ 

/* Put this away from the code */ 
fmtstr: .string "Hello %d %d\n" /* The \n needs to be double-backslashed in C */ 
+0

最初のレート..... – Homer6

関連する問題