Мое почтение всем. Есть очень неприятная проблема с линкером -- не хочет линковать файлы в том порядке, в каком ему указываешь. Опишу чуть подробнее: у меня есть 16/32битный .asm файл и 32битный .c файл. Оба скомпилированы в объектные ELF файлы. В 32битной части .asm файла есть вызовы ф-ий из .c файла. Конечная цель линкования -- плоский бинарник, но с условием, что .asm файл в нем должен идти первым, чего достичь не удается. Линковал так: 'ld --oformat=binary -Ttext=0x10000 test.asm test.c -o test'. Такое ощущение, что порядок указания объектных файлов роли не играет -- пробовал 'ld --oformat=binary -Ttext=0x10000 test.c test.asm -o test2' -- файлы test & test2 одинаковы. Попробовал так же линковать с помощью скрипта: Код (Text): STARTUP(pm.o) SECTIONS { . = 0x10000 .text : { pm.o(.text) console.o(.text) } .data : { *(.data) } .bss : { *(.bss) } } OUTPUT(test) OUTPUT_FORMAT(binary) и Код (Text): STARTUP(pm.o) SECTIONS { . = 0x10000 .init : { pm.o(.text) } .text : { console.o(.text) } .data : { *(.data) } .bss : { *(.bss) } } OUTPUT(test) OUTPUT_FORMAT(binary) эффект тот же. Безобразие происходит на: FreeBSD 6.0, binutils 2.17. Пробовал сначала на 2.15 -- то же самое. При этом на FreeBSD 4.6.2 с 'ld' версии 2.11.2 все Ок. Но беда в том, что 4.6.2 -- удаленный сервер, мне неподконтрольный, со старым 'gcc'. Как убедить линкер класть .asm в начале? В чем м.б. причина? Заранее благодарен .
А если получить раздельно два голых бинарника, а потом их просто склеить вместе (например при помощи cat) в нужном порядке?
Я уже думал об этом. Мешает то, что в .asm файле есть вызов ф-ии из .c файла -- поэтому удобно компилировать оба в объектный, а потом клеить линкером, чтобы он разрешил вызовы. Да и хотелось бы понять, почему ld капризничает -- это, как я понял, только у меня так происходит...
Вообще вся твоя конструкция очень напоминает загрузчик+kernel операционной системы. Есть такое? Если так, чем тебе может мешать вызов из asm файла? Ты ж все грузишь по известным тебе адресам, и ядро и загрузчик. Делай из asm-файла простой вызов call <имя_функции_в_С_файле>, и все. Только перед этим функцию надо экспортировать. Короче, посмотри вот тут http://sysbin.com/files/lowlevel/osdev9.htm живой пример.
kernel -- это громко сказано, я пока просто экспериментирую . Да, но для этого мне и надо .asm файл и .c файл сохранять как ELF -- чтобы линкер сделал за меня эту работу, а затем слил это все в плоский бинарник. Именно так я и делаю -- указываю .asm файл первым. Но он почему-то в конечном бинарнике идет вторым...
специально проверил Код (Text): /* a.S */ .text .long 0xAAAAAAAA .long 0xBBBBBBBB Код (Text): /* b.c */ void F() { int a = 5; } если link.ld изменить на то в
Дико извиняюсь, нашел проблему. Всего лишь навсего, FASM по умолчанию называет секцию кода '.flat', а не '.text', как было у меня скрипте. Всем спасибо (а отдельно rei3er -- навел на мысль проверить ).