Пытаюсь собрать два .o файла(c.o и kernel.o первый это ELF формат собранный в fasm, второй это "C" сорц собранный на gcc(тоже из MinGW) с параметром --ffreestanding) Почему-то под Linux все нормально собирается, а программа из MinGW - ld(Linker Dynamic) не пашет. В чем дело? вот сборка кода ..\fasm c.asm -m 65536 C:\MinGW\bin\gcc -ffreestanding -c -o kernel.o kernel.c C:\MinGW\bin\ld --oformat binary --section-start ".text"=0x200000 -o kernel1.bin c.o kernel.o ld пишет следующие C:\MinGW\bin\ld: cannot perform PE operations on non PE output file 'kernel.bin' если вместо binary формата указать pei-i386 c.o: In function 'go': (.flat+0x6): undefined reference to 'k_main' Хотя все это прекрасно линкуется под Linux(на родном ld)
Чтобы ld мог собирать не PE файлы его необходимо скомпилировать с соотвествующими опциями. Подробнее можно прочитать здесь. Скорее всего, ф-ии kernel.c были скомпилированы с конвенцией stdcall, которая помещает символ '_' в начале имени ф-ии + кое-что в конце. Чтобы этого не происходило ей необходимо дать конвенцию cdecl (и при этом учесть, что стек нужно почистить самому), либо использовать кросс-компилятор (по ссылке выше). nm поможет посмотреть, как именно названа ф-ия в файле kernel.o.
Спасибо что ответили на мой вопрос... Интересно где можно взять сорцы ld который под винду... если он шел в пакете binutils под MinGW Пишет что названа _k_main(а в сорцах просто k_main) видимо оно и значит что там stdcall(вроде как ето значит что параметры пихаются в стек в другом порядке, но что ето еще значит раз компил ругается). Что же вы предлагаете....? использовать кросс компилятор? а что же с ld(как мне линковать) Кстати получается что в Linux версии того же gcc компиляция идет без stdcall по дефолту? или как?
Взять binutils можно здесь. Как компилировать описано в статье. Можно попробовать применить опцию gcc '-fno-leading-underscore', но мне она когда-то не помогла, не знаю почему. stdcall кладет параметры в стек в том же порядке, что и cdecl, разница между ними в том, что в stdcall вызываемая ф-ия сама чистит стек с помощью инструкции 'ret N', а в cdecl стек чистит вызывающая ф-ия. Да, самое простое -- использовать кросс компилятор, и вместе с ним перекомпилировать ld. В Linux gcc был скомпилирован с опцией другой целевой платформы -- 'elf32-i386'. Почему mingw ld не может собирать файлы для другой целевой платформы, я не очень понимаю, это вопрос скорее в WASM.UNIX, но знаю, что проблема решается с помощью кросс-компилятора и перекомпилированных binutils (в состав которого входит ld).