2009-05-19 7 views
7

Ich mache wahrscheinlich etwas falsch, ein Neuling zu sein. Könnten Sie mir bitte helfen?"Datei nicht erkannt" bei der Verwendung des GNU-Linkers

ich ein einfaches Hallo Welt Programm in C geschrieben haben genannt hello.c und lief den folgenden Befehl ein:

gcc -S hello.c 

Das hello.s produziert. Dann habe ich die Datei mit GNU Assembler, as:

as hello.s 

, die ein nicht-ausführbaren a.out erzeugt, die noch verbunden werden muss, verstehe ich?

ich versuche, es zu verknüpfen, indem ld verwenden, etwa so:

ld a.out 

Aber erhalten folgende Fehlermeldung:

a.out: file not recognized: File truncated 

Und ld löscht meine Datei.

Dies ist ein x86 Ubuntu-System. Was mache ich falsch? Danke vielmals!

Antwort

6

Meine erste Frage wäre: Warum montieren Sie den Code? Wenn Sie möchten, dass der Assembler-Code, verwenden Sie unbedingt gcc -S, um es zu bekommen (zum Anzeigen, denke ich).

Aber Sie brauchen nicht, dass durch as laufen in Gang zu halten, benutzen Sie einfach:

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

Dieser erste Schritt, um die C-Quelle direkt in eine ausführbare Datei verwandeln, wird die zweite Sie Ihre Assembler geben .

Ihr spezifisches Problem kann sein, dass ld versucht, seine Ausgabe auf a.out zu schreiben. Wenn dies auch Ihre Eingabedatei ist, wird sie möglicherweise während der Ausführung von ld zerstört. Sie könnten versuchen, a.out in a.in umzubenennen, bevor Sie den Befehl ld ausführen: ld a.in.

+1

Um Ihre Frage zu beantworten, ich vermute, er versucht Assembly zu lernen ... – Zifre

+1

Ich realisiere das, aber ich möchte als und ld unabhängig von gcc verwenden. Ich lerne x86 Assembly. Die Ausgabe von gcc -S hilft mir zu sehen, wie gcc verschiedene C-Programme in Assembly implementiert. Dann kann ich mit diesem Assembler-Code modifizieren und spielen und ihn schließlich assemblieren und verknüpfen, indem ich as und ld benutze. Ich realisiere, dass gcc diese Dateien für mich zusammenstellen und verlinken kann, aber es verwendet nur as und ld in meinem Namen. Ich möchte als und ld direkt verwenden. –

3

EDIT: Okay, ich habe das alles auf meinem System ausprobiert, und ich denke, ich weiß, was das Problem ist. ld schreibt an a.out (seine Standardausgabedatei), während gleichzeitig von ihm gelesen wird. Versuchen Sie etwas wie folgt:

ld a.out -o myprog 
+0

'a.out' kann jede Art von Datei sein. Wenn "gcc" mit dem Flag "-S" aufgerufen wird, gibt es nur Assembler-Code aus, der von Menschen gelesen werden kann. Es wird nicht zusammengesetzt oder verknüpft. 'as' sollte definitiv nicht verlinken, das ist' ld's Job.Mit dem Flag "-o" können Sie nur den Dateinamen des Ergebnisses ändern, was auch immer das Ergebnis sein mag. –

+0

Ja .. aber der Punkt bleibt, ist, dass, wenn Sie keinen Ausgabedateinamen für ld angeben, die allererste Sache, die es tun wird, a.out abschneiden wird. Dann wird es auf seine Eingabedateien schauen. Wenn einer von ihnen a.out ist, wird er erkennen, dass er abgeschnitten wurde und fehlschlägt. Es löscht dann die unvollständige Ausgabedatei a.out. Verwenden Sie etwas auf und geben Sie das an ld. ld benötigt verschiedene Ein- und Ausgabedateien, es kann nicht "in Place" verlinkt werden. – pjc50

5

Hier ist, wie ich es tun:

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

Warum rufe ich gcc statt ld? Weil GCC darauf achtet, die C-Laufzeit zu verbinden und andere implementierungsabhängige Dinge zu tun. Wenn Sie das sehen wollen, verwenden Sie die Option --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

wieder installieren glibc-devel trotzdem können Sie und überprüfen, ob es funktioniert. dieser Prozess funktioniert für mich.