![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
Глянем размер простейшей программы для FP/M. Вот исходный код упомянутой hello.exe.
Заметьте: системный вызов fpm_puts() выглядит как простой вызов функции с параметрами.
Для каждого такого системного вызова линкер создаёт в секции .plt код размером 24 байта. Его задача - вытащить из глобальной таблицы смещений (GOT, или Global Offset Table) адрес процедуры, реализующей вызов, и туда перейти. Таблицу GOT формирует системный вызов rpm_execv() на стеке при запуске программы на выполнение. И заносит её адрес в таблицу векторов по адресу 20000010. Это для архитектуры ARMv6-M.
То есть весь hello.exe это 36+24 = 60 байт кода программы. Всё остальное в бинарном файле - накладные расходы на формат ELF.
Код здесь позиционно-независимый. На каком адресе файл окажется в файловой Flash-памяти, там и будет выполняться. Лишь бы лежал одним фрагментом.
Построим бинарник.#include <fpm/api.h>
int main()
{
fpm_puts("Hello, World!\r\n");
}
Вот результат дизассемблирования посредством arm-none-eabi-objdump.$ arm-none-eabi-gcc -mcpu=cortex-m0plus -mthumb -fPIC -O -Ifpm-base/include -c hello.c
$ arm-fpm-ld -shared -fPIC -e main hello.o -o hello.exe
$ arm-none-eabi-size hello.exe
text data bss dec hex filename
194 144 0 338 152 hello.exe
Размер главной функции main() составляет 16 байт комманд и 4 байта константы. Присоединим сюда также 16 байт текста сообщения в секции .rodata. В сумме 36 байт.hello.exe: file format elf32-littlearm
Disassembly of section .plt:
0000011c <.plt>:
11c: b407 push {r0, r1, r2}
11e: 4803 ldr r0, [pc, #12] @ (12c <.plt+0x10>)
120: 6800 ldr r0, [r0, #0]
122: 4903 ldr r1, [pc, #12] @ (130 <.plt+0x14>)
124: 5840 ldr r0, [r0, r1]
126: 9002 str r0, [sp, #8]
128: bd03 pop {r0, r0, pc}
12a: 46c0 nop
12c: 20000010 .word 0x20000010
130: 00000000 .word 0
Disassembly of section .text:
00000134 <main>:
134: b510 push {r4, lr}
136: 4803 ldr r0, [pc, #12] @ (144 <main+0x10>)
138: 4478 add r0, pc
13a: f7ff ffef bl 11c <.plt>
13e: 2000 movs r0, #0
140: bd10 pop {r4, pc}
142: 46c0 nop
144: 0000000c .word 0xc
Disassembly of section .rodata:
00000148 <.rodata>:
148: 6c6c6548
14c: 57202c6f
150: 646c726f
154: 000a0d21
Заметьте: системный вызов fpm_puts() выглядит как простой вызов функции с параметрами.
Для каждого такого системного вызова линкер создаёт в секции .plt код размером 24 байта. Его задача - вытащить из глобальной таблицы смещений (GOT, или Global Offset Table) адрес процедуры, реализующей вызов, и туда перейти. Таблицу GOT формирует системный вызов rpm_execv() на стеке при запуске программы на выполнение. И заносит её адрес в таблицу векторов по адресу 20000010. Это для архитектуры ARMv6-M.
То есть весь hello.exe это 36+24 = 60 байт кода программы. Всё остальное в бинарном файле - накладные расходы на формат ELF.
Код здесь позиционно-независимый. На каком адресе файл окажется в файловой Flash-памяти, там и будет выполняться. Лишь бы лежал одним фрагментом.
no subject
Date: 2025-01-18 16:50 (UTC)Точніше -- ще ні, але будуть.
Цікаво буде спостерігати за прогресом Вашої операційної системи!
no subject
Date: 2025-01-18 20:01 (UTC)