2015-12-06 19 views
9

Tôi đang học lắp ráp với NASM cho một lớp tôi có ở trường đại học. Tôi muốn liên kết Thư viện Thời gian C C với ld, nhưng tôi dường như không thể quấn đầu quanh nó. Tôi có một máy 64 bit với cài đặt Linux Mint.Làm thế nào để liên kết Thư viện C Runtime với 'ld'?

Lý do tôi nhầm lẫn là - với kiến ​​thức của tôi - thay vì liên kết thời gian chạy C, gcc sao chép những thứ bạn cần vào chương trình của mình. Mặc dù tôi có thể sai, vì vậy đừng ngần ngại sửa tôi bằng cách này, làm ơn.

Điều tôi đã làm cho đến thời điểm này là liên kết nó bằng cách sử dụng gcc. Điều đó tạo ra một mớ hỗn độn của một mã máy mà tôi không thể làm theo mặc dù, ngay cả đối với một chương trình nhỏ như hoán đổi rax với rbx, điều đó không tuyệt vời cho mục đích học tập. (Xin lưu ý rằng chương trình hoạt động.)

Tôi không chắc chắn nếu nó có liên quan, nhưng đây là những lệnh mà chúng tôi đang sử dụng để biên dịch và liên kết:

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

Cảm ơn bạn trước!


Kết luận:

Bây giờ tôi có một câu trả lời đúng cho câu hỏi, sau đây là một vài điều mà tôi muốn đề cập đến. Liên kết glibc động có thể được thực hiện như trong câu trả lời Z boson (đối với hệ thống 64 bit). Nếu bạn muốn làm điều đó tĩnh, do follow this link (tôi đang đăng lại từ Z boson 's câu trả lời).

Đây là một bài viết mà Jester đăng, về how programs start in linux.

Để xem nội dung gcc liên kết số .o -s của bạn, hãy dùng thử lệnh sau: gcc -v -o swap swap.o. Lưu ý rằng 'v' là viết tắt của 'verbose'.

Ngoài ra, you should read this nếu bạn quan tâm đến việc lắp ráp 64 bit.

Cảm ơn bạn để có câu trả lời và thông tin chi tiết hữu ích! Kết thúc bài phát biểu.

+2

Câu trả lời ngắn gọn: không. Thật không may libc đi kèm với không chỉ thư viện động, mà là một loạt các đối tượng tĩnh cần thiết để khởi tạo và tắt máy. Nếu bạn thực sự muốn làm điều đó, hãy sử dụng 'gcc -v' để xem những phần cần thiết là gì. Bạn có thể quan tâm đến [bài viết tuyệt vời này về việc khởi động chương trình] (http://dbp-consulting.com/tutorials/debugging/linuxProgramStartup.html). – Jester

+0

'gcc -o swap swap.o' liên kết thời gian chạy. 'ld -o swap swap.o' không. Liên kết bao gồm sao chép phần lớn ish của thời gian chạy sang thực thi. Vấn đề chính xác là gì? –

+0

@Jester Tôi sẽ xem xét điều đó ngay bây giờ! – mrDudePerson

Trả lời

4

Dưới đây là một ví dụ trong đó sử dụng libc mà không sử dụng 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 

Compile và liên kết như thế này:

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

này đã làm việc tốt cho đến nay đối với tôi nhưng đối với static linkage it's complicated.

+0

Cảm ơn bạn tôi sẽ dùng thử sau. Nếu nó hoạt động, tôi sẽ chọn đây là câu trả lời đúng :) – mrDudePerson

+0

Vâng, nó hoạt động! Cảm ơn bạn :) – mrDudePerson

2

Nếu bạn muốn gọi các chức năng thư viện đơn giản như atoi, nhưng vẫn tránh sử dụng thời gian chạy C, bạn có thể thực hiện điều đó. (Ví dụ: bạn viết _start, thay vì chỉ viết một main đó được gọi sau khi một bó mã nồi hơi-tấm chạy.)

gcc -o swap -nostartfiles swap.o 

Khi mọi người nói trong ý kiến, một số bộ phận của glibc phụ thuộc vào nhà xây dựng/destructors chạy từ các tệp khởi động chuẩn. Có lẽ đây là trường hợp cho stdio (đặt/printf/scanf/getchar), và có thể malloc. Rất nhiều chức năng là các hàm "thuần túy" mà chỉ xử lý đầu vào mà chúng được đưa ra. sprintf/sscanf có thể được sử dụng.

Ví dụ:

$ 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

Vâng, cảm ơn bạn, điều đó sẽ hoàn hảo! :) – mrDudePerson

+0

@mrDudePerson: Đừng quên "chấp nhận" câu trả lời đã giải quyết được vấn đề của bạn. (nhấp vào hộp kiểm dưới mũi tên bỏ phiếu lên/xuống). Nếu không câu hỏi vẫn hiển thị như chưa được trả lời. –

Các vấn đề liên quan