2009-05-19 30 views
7

Tôi có thể đang làm điều gì sai, là một người mới. Ông có thể giúp tôi không?"tệp không được nhận dạng" trong khi sử dụng trình liên kết GNU

Tôi đã viết một chương trình Hello World đơn giản trong C gọi là hello.c, và chạy lệnh sau:

gcc -S hello.c 

Đó sản xuất hello.s. Sau đó, tôi sử dụng mà tập tin với GNU lắp ráp, as:

as hello.s 

nào sản xuất một tổ chức phi thực thi a.out, mà vẫn cần phải được liên kết, tôi hiểu không?

tôi cố gắng liên kết nó bằng cách sử dụng ld, như vậy:

ld a.out 

Nhưng nhận được lỗi sau:

a.out: file not recognized: File truncated 

ld xóa tập tin của tôi.

Đây là hệ thống Ubuntu x86. Tôi đang làm gì sai? Cảm ơn nhiều!

Trả lời

6

Câu hỏi đầu tiên của tôi là: tại sao bạn lắp ráp mã? Nếu bạn muốn mã lắp ráp, bằng mọi cách, hãy sử dụng gcc -S để lấy nó (để xem, tôi đoán).

Nhưng bạn không cần phải chạy mà qua as để tiếp tục đi, chỉ cần sử dụng:

gcc -o hello hello.c 
gcc -S hello.c 

Đó Bước đầu tiên sẽ biến nguồn C trực tiếp vào một file thực thi, thứ hai sẽ cung cấp cho bạn nguồn lắp ráp của bạn .

Vấn đề cụ thể của bạn có thể là ld cố gắng viết đầu ra của nó là a.out. Nếu đó cũng là tập tin đầu vào của bạn, nó cũng có thể bị phá hủy trong quá trình chạy ld. Bạn có thể thử đổi tên a.out thành a.in trước khi chạy lệnh ld: ld a.in.

+1

Để trả lời câu hỏi của bạn, tôi đoán anh ấy đang cố gắng học lắp ráp ... – Zifre

+1

Tôi nhận ra rằng, nhưng tôi muốn sử dụng như và ld độc lập với gcc. Tôi đang học x86. Đầu ra của gcc -S giúp tôi xem cách gcc thực hiện các chương trình C khác nhau trong assembly. Sau đó, tôi có thể sửa đổi và chơi với mã lắp ráp đó và cuối cùng lắp ráp và liên kết nó bản thân mình, sử dụng như và ld. Tôi nhận ra gcc có thể lắp ráp và liên kết các tệp này cho tôi, nhưng nó chỉ sử dụng như và ld thay cho tôi. Tôi muốn sử dụng như và ld trực tiếp. –

3

EDIT: được rồi, tôi đã thử tất cả điều này trên hệ thống của mình và tôi nghĩ rằng tôi biết vấn đề là gì. ld đang ghi vào a.out (tệp đầu ra mặc định của nó), trong khi đọc từ nó cùng một lúc. Hãy thử một cái gì đó như thế này:

ld a.out -o myprog 
+0

'a.out' có thể là bất kỳ loại tệp nào. Bằng cách gọi 'gcc' với cờ' -S', nó chỉ xuất ra kết hợp, mã có thể đọc được. Nó không lắp ráp hoặc liên kết nó. 'như' nhất định không nên liên kết nó, đó là công việc của' ld'.Cờ '-o' chỉ cho phép bạn thay đổi tên tệp của kết quả, bất kể kết quả đó có thể là gì. –

+0

Có .. nhưng điểm vẫn là nếu bạn không chỉ định một tên tập tin đầu ra cho ld điều đầu tiên nó sẽ làm là cắt ngắn a.out. Sau đó, nó sẽ xem xét các tập tin đầu vào của nó. Nếu một trong số đó là a.out nó sẽ phát hiện ra rằng nó đã cắt ngắn và thất bại. Sau đó nó xóa tệp đầu ra không đầy đủ a.out. Sử dụng -o một số thứ trên và đưa nó cho ld. ld cần các tệp đầu vào và đầu ra khác nhau, nó không thể liên kết "tại chỗ". – pjc50

5

Sau đây là cách tôi làm điều đó:

> gcc -S forums.c 
> as forums.s -o forums.o 
> gcc forums.o -o forums 
> ./forums 
test 

Tại sao tôi gọi gcc thay vì ld? Vì GCC quan tâm đến việc liên kết thời gian chạy C và thực hiện các công cụ phụ thuộc vào việc triển khai khác. Nếu bạn muốn để thấy rằng, sử dụng tùy chọn --verbose:

> gcc --verbose forums.o -o forums 
Using built-in specs. 
Target: i686-pc-linux-gnu 
Configured with: ../configure --prefix=/usr --enable-shared --enable-languages=c,c++,fortran,objc,obj-c++ --enable-threads=posix --mandir=/usr/share/man --infodir=/usr/share/info --enable-__cxa_atexit --disable-multilib --libdir=/usr/lib --libexecdir=/usr/lib --enable-clocale=gnu --disable-libstdcxx-pch --with-tune=generic 
Thread model: posix 
gcc version 4.4.0 (GCC) 
COMPILER_PATH=/usr/lib/gcc/i686-pc-linux-gnu/4.4.0/:/usr/lib/gcc/i686-pc-linux-gnu/4.4.0/:/usr/lib/gcc/i686-pc-linux-gnu/:/usr/lib/gcc/i686-pc-linux-gnu/4.4.0/:/usr/lib/gcc/i686-pc-linux-gnu/:/usr/lib/gcc/i686-pc-linux-gnu/4.4.0/:/usr/lib/gcc/i686-pc-linux-gnu/ 
LIBRARY_PATH=/usr/lib/gcc/i686-pc-linux-gnu/4.4.0/:/usr/lib/gcc/i686-pc-linux-gnu/4.4.0/:/usr/lib/gcc/i686-pc-linux-gnu/4.4.0/../../../:/lib/:/usr/lib/ 
COLLECT_GCC_OPTIONS='-v' '-o' 'forums' '-mtune=generic' 
/usr/lib/gcc/i686-pc-linux-gnu/4.4.0/collect2 --eh-frame-hdr -m elf_i386 --hash-style=both -dynamic-linker /lib/ld-linux.so.2 -o forums /usr/lib/gcc/i686-pc-linux-gnu/4.4.0/../../../crt1.o /usr/lib/gcc/i686-pc-linux-gnu/4.4.0/../../../crti.o /usr/lib/gcc/i686-pc-linux-gnu/4.4.0/crtbegin.o -L/usr/lib/gcc/i686-pc-linux-gnu/4.4.0 -L/usr/lib/gcc/i686-pc-linux-gnu/4.4.0 -L/usr/lib/gcc/i686-pc-linux-gnu/4.4.0/../../.. forums.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/i686-pc-linux-gnu/4.4.0/crtend.o /usr/lib/gcc/i686-pc-linux-gnu/4.4.0/../../../crtn.o 
1

cài đặt lại glibc-devel anyway bạn có thể và kiểm tra xem nó hoạt động. quá trình này làm việc cho tôi.

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