2015-12-06 33 views
9

我正在與NASM一起學習大學課程。 我想鏈接C運行時庫ld,但我似乎無法繞過它。我有一臺安裝了Linux Mint64 bit機器。如何將C運行時庫與'ld'鏈接?

我感到困惑的原因是 - 據我所知 - 而不是鏈接C運行時,gcc將您需要的東西複製到您的程序中。我可能是錯的,所以請毫不猶豫地糾正我。

我到目前爲止所做的是,使用gcc鏈接它。這會產生一個我無法遵循的機器代碼,即使對於像raxrbx這樣的小程序,這對於學習目的來說也不是很好。 (請注意,程序工作。)

我不知道,如果是相關的,但這些都是我使用編譯命令和鏈接:

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

預先感謝您!


結論:

現在,我有一個正確答案的問題,這裏是我想提幾件事情。動態鏈接glibc可以像Z boson的答案(對於64位系統)那樣完成。如果你想靜態地做,do follow this link(我從Z玻色子的答案重新張貼)。

這是Jester已發佈,約how programs start in linux的文章。

要查看gcc如何鏈接您的.o -s,請嘗試此命令:gcc -v -o swap swap.o。請注意'v'代表'verbose'。

另外,you should read this如果你有興趣在64位程序集。

感謝爲您的答案和有益的見解!講話結束。

+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

這裏是使用libc而不使用GCC一個例子。

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 

編譯和鏈接如下:

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

這對我而且對static linkage it's complicated工作的罰款爲止。

+0

謝謝我以後再試一試。如果它有效,我會選擇這個作爲正確的答案:) – mrDudePerson

+0

是的,它的工作原理!謝謝 :) – mrDudePerson

2

如果你想調用簡單的庫函數,如atoi,但仍然避免使用C運行時,你可以這樣做。 (即你寫_start,而不是僅僅寫一個main那被一堆的鍋爐板代碼後調用運行。)

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:不要忘記「接受」解決您的問題的答案。 (點擊向上/向下箭頭下的複選框)。否則,問題仍然顯示爲未答覆。 –