2016-09-09 23 views
0

私はアセンブリコードで外部関数を使用しようとしました:アセンブラで外部関数を呼び出す方法は?

 .section .rodata 
    .LC0: 
     .string "My number is: %lld" 
     .text 
     .globl start 
    start: 
     pushq %rbp 
     movq %rsp, %rbp 
     subq $16, %rsp 
     movq $12345, -8(%rbp) 
     movq -8(%rbp), %rax 
     movq %rax, %rsi 
     movl $.LC0, %edi 
     movl $0, %eax 

     call printf # my external function 

     # exit-syscall 
     mov $1, %eax 
     mov $0, %ebx 
     int $0x80 

私が組み立てられ、とリンク:

as -o myObjfile.o mySourcefile.s 
ld -e start -o myProgram -lc myObjfile.o 

実行ファイルが構築され、それは実行されませんので、何が間違っていますそれ?

+0

と明示的にリンクしてみてください、あなたはどのようなエラーメッセージを得るのですか? –

+1

ところで、コンパイラの出力を出発点として使用するのが一般的ですが、* optimize *コンパイラの出力を使うべきです。 'gcc -O3 -S'を使います。 64ビットコードでは、64ビットABI(int $ 0x80ではなく 'syscall'命令)を使用します。 argsのシステムコール番号とレジスタも異なります。 docsについては、[x86タグwiki](http://stackoverflow.com/tags/x86/info)を参照してください。また、[mainの代わりに '_start'を定義するコードのビルドについてはこの答えですが、まだlibcにリンクしています](http://stackoverflow.com/questions/36861903/assembling-32-bit-binaries-on-a-64-bit -system-gnu-toolchain/36901649#36901649)。 –

+1

あなたはすでに_C_ライブラリとリンクしているので、_C_ランタイムも使用することをお勧めします。 'start'を' main'に変更し、 'int 0x80'(またはシステムコール)の代わりに' mov%rbp、%rsp' 'pop%rbp''ret'を実行します。 'ret'は、この場合、_C_ランタイムに戻り、プロセスを正常に終了し、出力バッファをフラッシュします。あなたは 'gcc -o myProgram mySourcefile.s'のようなものでGCCをコンパイル/アセンブルすることができます –

答えて

-2

コールする関数がCライブラリにある場合、正しく理解すれば、それを外部関数として宣言することができます。

.section .rodata 
.LC0: 
    .string "My number is: %lld" 
    .text 
    .extern printf #declaring the external function 
    .globl start 
start: 
    pushq %rbp 
    movq %rsp, %rbp 
    subq $16, %rsp 
    movq $12345, -8(%rbp) 
    movq -8(%rbp), %rax 
    movq %rax, %rsi 
    movl $.LC0, %edi 
    movl $0, %eax 

    call printf # my external function 

    # exit-syscall 
    mov $1, %eax 
    mov $0, %ebx 
    int $0x80 

これが機能しない場合がSTDLIB.H

+1

UNIXアセンブラで '.extern'は必要ありません。また、OPは彼のコードが構築されていると言っているので、これは問題にはなりません。ダウン投票。 – fuz

+0

はい、gcc/clangで正しく構築されます。 'as -o myObj.o mySrc.S'と' ld -o myExe myObj.o -lc'を使ったビルドがなぜ実行できないのか誰かが知っていればうまくいくでしょう。 –

+0

リンクプロセスだけが失敗すると思われます。私が上記のように 'as 'を実行し、その出力を' -nostartfiles'フラグを使って 'cc'とリンクすると、実行ファイルは大丈夫です。 –

関連する問題