2015-12-06 5 views
9

私は大学で授業を受けるためのNASMでアセンブリを学んでいます。 Cランタイムライブラリldとリンクしたいと思っていますが、私はその周りに私の頭を包んでいるようには見えません。私はLinux Mintがインストールされた64 bitマシンを持っています。Cランタイムライブラリを 'ld'とリンクさせる方法は?

私は混乱している理由はある - 私の知識に - 代わりに、Cランタイム、gccコピーし、あなたのプログラムに必要なものをリンクします。私は間違っているかもしれないので、これで私を修正するのをためらってください。

私がこれまで行ったことは、gccを使ってリンクすることです。これは、とrbxを交換するような小さなプログラムであっても、学習にはあまり役に立ちません。 (プログラムが動作することに注意してください。)

を、私はそれが関連するかどうか分からないが、これらは私がコンパイルに使用しているコマンドとリンクしている:

# compilation 
nasm -f elf64 swap.asm 
# gcc 
gcc -o swap swap.o 
# ld, no c runtime 
ld -s -o swap swap.o 

は、事前にありがとうございます!


結論:

今、私は質問に対する適切な答えを持っていることを、ここで私が言及したいと思いますいくつかあります。 glibcを動的にリンクすることは、Zボソンの回答(64ビットシステムの場合)のように行うことができます。あなたがそれを静的にしたいのであれば、do follow this link(私がZボソンの答えから転載していること)。

ここに記事Jesterが掲載されています。約how programs start in linuxです。

gccがあなたの.o -sをリンクするかどうかを確認するには、このコマンドを試してみてください:gcc -v -o swap swap.o。 'v'は 'verbose'の略です。

また、64ビットアセンブリに興味がある場合はyou should read thisです。

あなたの答えで役立つ洞察力のためのあなたをありがとう!演説の終わり。

+2

短い回答:しないでください。残念ながら、libcには動的ライブラリだけでなく、初期化とシャットダウンに必要な静的オブジェクトがたくさんあります。本当にやりたければ、 'gcc -v'を使って必要な部分が何であるかを見てください。この[プログラムの起動に関するすばらしい記事](http://dbp-consulting.com/tutorials/debugging/linuxProgramStartup.html)に興味があるかもしれません。 – Jester

+0

'gcc -o swap swap.o'はランタイムをリンクします。 'ld -o swap swap.o'はしません。リンクするには、ランタイムの大規模な部分を実行可能ファイルにコピーすることが含まれます。問題は何ですか? –

+0

@Jesterそれを今見てみましょう! – mrDudePerson

答えて

4

はGCCを使用せずにlibcを使用する例です。このようなコンパイルとリンク

extern printf 
extern _exit 

section .data 
    hello:  db 'Hello world!',10 

section .text 
    global _start 
_start: 
    xor eax, eax 
    mov edi, hello 
    call printf 
    mov rax, 0  
    jmp _exit 

:これは私のためではなくstatic linkage it's complicatedのために、これまでうまく働いてい

nasm -f elf64 hello.asm 
ld hello.o -dynamic-linker /lib64/ld-linux-x86-64.so.2 -lc -melf_x86_64 

+0

ありがとうございます。後で試してみます。それが動作する場合、私はこれを正しい答えとして選択します:) – mrDudePerson

+0

はい、それは動作します!ありがとうございました :) – mrDudePerson

2

atoiのような単純なライブラリ関数を呼び出すには、Cランタイムの使用を避けたい場合は、そのようにすることができます。人々がコメントで言うように(つまり、あなたがいうだけで、ボイラープレートコードの束を実行した後に呼び出されますmainを書くよりも、_startを書いてください。)

gcc -o swap -nostartfiles swap.o 

、glibcのいくつかの部分から実行するコンストラクタ/デストラクタに依存します標準のスタートアップファイル。おそらくこれはstdio(puts/printf/scanf/getchar)の場合であり、おそらくmallocです。多くの関数は、与えられた入力をただ処理する "純粋な"関数です。 sprintf/sscanfを使用しても問題ありません。例えば

:ここ

$ cat >exit64.asm <<EOF 
section .text 

extern exit 

global _start 
_start: 

    xor edi, edi 
    jmp exit   ; doesn't return, so optimize like a tail-call 

    ;; or make the syscall directly, if the jmp is commented 
    mov eax, 231 ; exit(0) 
    syscall 

; movl eax, 1  ; 32bit call 
; int 0x80 
EOF 

$ yasm -felf64 exit64.asm && gcc -nostartfiles exit64.o -o exit64-dynamic 
$ nm exit64-dynamic 
0000000000601020 D __bss_start 
0000000000600ec0 d _DYNAMIC 
0000000000601020 D _edata 
0000000000601020 D _end 
       U [email protected]@GLIBC_2.2.5 
0000000000601000 d _GLOBAL_OFFSET_TABLE_ 
00000000004002d0 T _start 
$ ltrace ./exit64-dynamic 
enable_breakpoint pid=11334, addr=0x1, symbol=(null): Input/output error 
exit(0 <no return ...> 
+++ exited (status 0) +++ 
$ strace ... # shows the usual system calls by the runtime dynamic linker 
+0

はい、ありがとう、完璧ですよ! :) – mrDudePerson

+0

@mrDudePerson:あなたの問題を解決した答えを「受け入れる」ことを忘れないでください。 (上下の矢印の下にあるチェックボックスをクリックしてください)。さもなければ質問は未回答のままで現れます。 –

関連する問題