Hinzufügen von führenden Unterstrichen zu Assemblersymbolen mit GCC unter Win32?

Ich habe ein Stück C-Code, der eine in Assembly definierte Funktion aufruft. Nehmen wir zum Beispiel an, foo.c enthält:

<code>int bar(int x);  /* returns 2x */
int main(int argc, char *argv[]) { return bar(7); }
</code>

Und bar.s enthält die Implementierung von bar () in der x86-Assembly:

<code>.global bar
bar:    movl 4(%esp), %eax
        addl %eax, %eax
        ret
</code>

Unter Linux kann ich diese Quellen wie folgt einfach kompilieren und mit GCC verknüpfen:

<code>% gcc -o test foo.c bar.s
% ./test; echo $?
14
</code>

Unter Windows mit MinGW schlägt dies mit dem Fehler "undefinierter Verweis auf` bar '"fehl. Es hat sich herausgestellt, dass unter Windows allen Bezeichnern von Funktionen mit C-Aufrufkonvention ein Unterstrich vorangestellt ist. Da jedoch "bar" in der Assembly definiert ist, wird dieses Präfix nicht abgerufen, und die Verknüpfung schlägt fehl. (Die Fehlermeldung beschwert sich also tatsächlich über das Fehlen des Symbols _bar, nicht bar.)

Zusammenfassen:

<code>% gcc -c foo.c bar.s
% nm foo.o bar.o
foo.o:
00000000 b .bss
00000000 d .data
00000000 t .text
         U ___main
         U _bar
00000000 T _main

bar.o:
00000000 b .bss
00000000 d .data
00000000 t .text
00000000 T bar
</code>

Die Frage ist nun: Wie kann ich das schön lösen? Wenn ich nur für Windows schreiben würde, könnte ich einfach den Unterstrich zum Bezeichner in bar.s hinzufügen, aber dann bricht der Code unter Linux. Ich habe gcc's angeschaut-fleading-underscore und-fno-leading-underscore Optionen, aber keine scheint etwas zu tun (zumindest unter Windows).

Die einzige Alternative, die ich jetzt sehe, besteht darin, die Assembly-Datei durch den C-Präprozessor zu leiten und alle deklarierten Symbole manuell neu zu definieren, wenn WIN32 definiert ist, aber das ist auch nicht sehr hübsch.

Hat jemand eine saubere Lösung dafür? Vielleicht eine Compiler-Option, die ich beaufsichtigt habe? Vielleicht unterstützt der GNU-Assembler eine Möglichkeit, genau zu definieren, dass dieses spezielle Symbol auf eine Funktion mit C-Aufrufkonvention verweist und als solche entstellt werden sollte? Irgendwelche anderen Ideen?

Antworten auf die Frage(4)

Ihre Antwort auf die Frage