Erste Untersuchung:
A. C
extern void b(void);
void a(void);
int main() {
a();
return 0;
}
void a() {
b();
}
B. S
.extern a
b:
jmp a
b.c
void a(void);
void b(void)
{
a();
}
Ausgabe
$ gcc -c a.c
$ gcc -c b.c -o b_gcc.o
$ as b.S -o b_as.o
$ gcc a.o b_gcc.o -o test_gcc
$ gcc a.o b_as.o -o test_as
a.o: In function `a':
a.c:(.text+0x15): undefined reference to `b'
collect2: error: ld returned 1 exit status
Also, was soll das? Warum ist es in Ordnung mit GCC, aber nicht mit GAS?
$ objdump -t b_gcc.o > syms_gcc
$ objdump -t b_as.o > syms_as
$ diff syms_gcc syms_as
2c2
< b_gcc.o: file format elf64-x86-64
---
> b_as.o: file format elf64-x86-64
5d4
< 0000000000000000 l df *ABS* 0000000000000000 b.c
9,12c8
< 0000000000000000 l d .note.GNU-stack 0000000000000000 .note.GNU-stack
< 0000000000000000 l d .eh_frame 0000000000000000 .eh_frame
< 0000000000000000 l d .comment 0000000000000000 .comment
< 0000000000000000 g F .text 000000000000000b b
---
> 0000000000000000 l .text 0000000000000000 b
Okay, so macht gcc
b
ein globales Symbol. Lets versuchen .global b
in b.S
:
$ as b.S -o b_as2.o
$ gcc a.o b_as2.o
$
Erfolg. So gcc
/ld
wird Multi-Pass-Symbol-Auflösung für alles, was nicht in einer statischen Bibliothek ist. Aber es nur sucht nach globalen Symbolen. Hier ist das letzte b.S
:
.extern a
.global b
b:
jmp a
Ein paar Fragen: (A) Was Asm ist das Targeting? nichts von Yasm, Nasm oder Gas mag es. (b) Sie müssen 'void a()' in 'a.c' weiterleiten oder es wird nicht kompiliert. (c) Ändern von 'b()' in eine C-Funktion und versuchen Sie Ihren Link-Befehl funktioniert gut. Soweit ich weiß, ist das Verhalten der Linker für statische Bibliotheken das einzige Mal, dass Sie die Art von Abhängigkeiten erhalten, über die Sie sprechen. Können Sie die Frage aktualisieren, um ein funktionierendes Beispiel für das Problem zu geben? – lockcmpxchg8b
Es ist Gnu als. Ich schreibe Betriebssystem, das groß gewachsen ist, und ich dachte über ein Beispiel wie folgt. –
sry, mein Problem mit Gas war, dass meine erste Untersuchung auf Mingw war. Zu einem richtigen Linux wechseln lassen Sie mich Ihr Beispiel gut zusammenbauen. Lösung unten. TL; DR: Das Problem ist, dass "b" nicht global ist. – lockcmpxchg8b