Я использую 64-битную linux машину с компилятором x84-elf64-g cc. Я только начал программирование низкого уровня и хотел бы понять, как код C фактически переводится в двоичный код. Это в основном для разработки операционных систем, так как я знаю, что процессор не понимает ELF или любой другой формат, а понимает только двоичный.
Например, следующий файл c:
//test.c
int func()
{
return 0x12345678;
}
Когда я компилирую с g cc:
gcc test.c
, я получаю следующую ошибку:
(.text+0x20): undefined reference to `main'
collect2: error: ld returned 1 exit status
Итак, я предполагаю, что есть проблема с линкер. Я делаю:
gcc test.c -c
Я получаю объектный файл ELF, и я делаю objdump и получаю ожидаемое:
0000000000000000 <func>:
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: b8 78 56 34 12 mov $0x12345678,%eax
9: 5d pop %rbp
a: c3 retq
Но когда я "кросс-компилирую" 32-битную версию, используя опция -m32 и objdump, я получаю:
hello.o: file format elf32-i386
Disassembly of section .text:
00000000 <func>:
0: 55 push %ebp
1: 89 e5 mov %esp,%ebp
3: e8 fc ff ff ff call 4 <func+0x4>
8: 05 01 00 00 00 add $0x1,%eax
d: b8 78 56 34 12 mov $0x12345678,%eax
12: 5d pop %ebp
13: c3 ret
Disassembly of section .text.__x86.get_pc_thunk.ax:
00000000 <__x86.get_pc_thunk.ax>:
0: 8b 04 24 mov (%esp),%eax
3: c3 ret
В предыдущем ответе я читал, что это связано с позиционно-независимым кодом: неопределенная ссылка на ` _GLOBAL_OFFSET_TABLE_ 'в g cc 32-битный код для тривиальной функции, отдельно стоящая ОС
Почему происходят такие изменения при компиляции с параметром -m32? Более того, мне посоветовали использовать опцию -ffreestanding при компиляции, но здесь, похоже, это не дает никакого эффекта. Я читал, что -ffreedtanding говорит компилятору, что стандартной библиотеки нет, так что же тогда -nostdlib?
Примечание: я относительно новичок в этом hardcore c программирования, и я думаю, что главная проблема здесь в том, что я не очень понимаю, как работают компоновщики / компиляторы. :(