Добавление лидирующих подчеркиваний к ассемблерным символам с помощью GCC на Win32?
У меня есть кусок кода C, который вызывает функцию, определенную в сборке. В качестве примера, скажем, foo.c содержит:
<code>int bar(int x); /* returns 2x */ int main(int argc, char *argv[]) { return bar(7); } </code>
И bar.s содержит реализацию bar () в сборке x86:
<code>.global bar bar: movl 4(%esp), %eax addl %eax, %eax ret </code>
В Linux я могу легко скомпилировать и связать эти источники с GCC следующим образом:
<code>% gcc -o test foo.c bar.s % ./test; echo $? 14 </code>
В Windows с MinGW это происходит с ошибкой «неопределенная ссылка на« bar »». Оказывается, причина этого в том, что в Windows все идентификаторы функций с соглашением о вызовах C начинаются с подчеркивания, но так как & quot; bar & quot; определен в сборке, он не получает этот префикс, и связывание не выполняется. (Таким образом, сообщение об ошибке на самом деле жалуется на отсутствие символа _bar, а не bar.)
Подвести итоги:
<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>
Теперь возникает вопрос: как я могу решить это красиво? Если бы я писал только для Windows, я мог бы просто добавить подчеркивание к идентификатору в bar.s, но тогда код ломался в Linux. Я смотрел на gcc-fleading-underscore
а также-fno-leading-underscore
параметры, но ни один, кажется, ничего не делает (по крайней мере, в Windows).
Единственная альтернатива, которую я вижу сейчас, - это передача файла сборки через препроцессор C и переопределение всех объявленных символов вручную, если определен WIN32, но это тоже не очень красиво.
У кого-нибудь есть чистое решение для этого? Возможно, вариант компилятора, который я наблюдал? Может быть, ассемблер GNU поддерживает способ указать, что этот конкретный символ относится к функции, использующей соглашение о вызовах C, и должен быть искажен как таковой? Есть еще идеи?