Ну, то есть, какие байты должны быть первыми, какие следующие за что они отвечают, из чего вообще состоит исполняемый файл, есть ли в ней что-то вроде сегментов, если есть - сколько, как их правильно создавать, есть ли заголовки, и что с ними да как, и т. д. и т. п., ну Вы поняли
Хочу написать маленький кросс компилятор.
Где можно найти спецификацию исполняемых файлов Колибри ОС?
Формат очень простой.
Первые 8 байт -- это символы "MENUET01",
дальше следуют семь четырехбайтовых полей в таком порядке:
1) версия
2) адрес точки старта программы (адрес машинной инструкции с которой начнется выполнение)
3) размер файла
4) потребное количество памяти для загрузки программы, сумма складывается из:
- размер файла
- размер глобальных переменных
- размер стэка -- разработчик может определить размер стэка по своему усмотрению (я задаю 1 Мб)
- размер двух текстовых строк: для параметров и для имени исполняемого файла (argv[0] в языке C) -- разработчик определяет длину строк по своему усмотрению (я задаю 2048 байт для каждой). После запуска программы ОС запишет туда параметры и путь исп. файла
- "на всякий случай", я добавляю еще 4096 байт
5) начальное значение регистра esp (т. к. стэк в x86 растет в сторону меньших адресов, начальное значение должно быть адресом конца области стэка)
6) адрес строки параметров
7) адрес строки пути исполняемого файла
Все адреса задаются относительно начала файла (адрес загрузки = 0).
Это создает некоторые проблемы: нулевой адрес считается корректным.
Если программа прочитает данные по адресу 0x0, то там будет текст "MENUET01".
Никаких секций, сегментов -- нет. Есть только вышеописанный заголовок (36 байт). После него следуют код и данные в произвольном порядке.
Первые 8 байт -- это символы "MENUET01",
дальше следуют семь четырехбайтовых полей в таком порядке:
1) версия
2) адрес точки старта программы (адрес машинной инструкции с которой начнется выполнение)
3) размер файла
4) потребное количество памяти для загрузки программы, сумма складывается из:
- размер файла
- размер глобальных переменных
- размер стэка -- разработчик может определить размер стэка по своему усмотрению (я задаю 1 Мб)
- размер двух текстовых строк: для параметров и для имени исполняемого файла (argv[0] в языке C) -- разработчик определяет длину строк по своему усмотрению (я задаю 2048 байт для каждой). После запуска программы ОС запишет туда параметры и путь исп. файла
- "на всякий случай", я добавляю еще 4096 байт
5) начальное значение регистра esp (т. к. стэк в x86 растет в сторону меньших адресов, начальное значение должно быть адресом конца области стэка)
6) адрес строки параметров
7) адрес строки пути исполняемого файла
Все адреса задаются относительно начала файла (адрес загрузки = 0).
Это создает некоторые проблемы: нулевой адрес считается корректным.
Если программа прочитает данные по адресу 0x0, то там будет текст "MENUET01".
Никаких секций, сегментов -- нет. Есть только вышеописанный заголовок (36 байт). После него следуют код и данные в произвольном порядке.
Если интересует, то в одном из моих проектов заголовок исполняемого файла KolibriOS определён вот так:Возможно, также интересен будет линкер-скрипт.
Для примера линкер-скрипт из BigSample http://board.kolibrios.org/viewtopic.php?f=2&t=3587А вот из исходника программы Timer http://websvn.kolibrios.org/filedetails ... sm#line-39
Code: Select all
Type
AppHeader = Packed Record
Signature: Packed Array [0..7] Of Char;
Version: Dword;
EntryPoint: Dword;
EndImage: Dword;
Memory: Dword;
StackTop: Dword;
CmdLine: Dword;
FilePath: Dword;
End;
Для примера линкер-скрипт из BigSample http://board.kolibrios.org/viewtopic.php?f=2&t=3587
Code: Select all
PATH_SIZE = 1024;
PARAMS_SIZE = 256;
STACK_SIZE = 1024;
SECTIONS
{
.all : AT(0){
LONG(0x554e454D);
LONG(0x31305445);
LONG(1);
LONG("@Main");
LONG(END);
LONG($END + PATH_SIZE + PARAMS_SIZE + STACK_SIZE);
LONG($END + PATH_SIZE + PARAMS_SIZE + STACK_SIZE);
LONG($END + PATH_SIZE);
LONG($END);
*(.text)
*(code)
*(.rdata)
*(const)
*(CONST)
*(.data)
*(data)
}
END = .;
.bss ALIGN(16) : {*(.bss)}
$END = .;
}
Code: Select all
STACK_SIZE equ 256
...
MENUET01 db 'MENUET01'
version dd 1
program.start dd START
program.end dd END
program.memory dd END + STACK_SIZE
program.stack dd END + STACK_SIZE
program.params dd 0
program.path dd 0
...
START:
...
END:
Понял, всем спасибо!
Уточню, что программист записывает туда адрес буфера, в который будут скопированы аргументы командной строки при старте программы. А буфер должен быть выделен где-то внутри самой программы при помощи resb или как-то так.akron1 wrote:6) адрес строки параметров
Я сначала подумал, что при запуске система сама записывает туда непосредственно указатель на строку с аргументами.
И еще, в буфер копируются только аргументы, без имени файла, просто строка аргументов.
- Attachments
-
-
kosargv.png (22.77 KiB)Viewed 9021 times
-
Кросс-компилятора нет, на за то есть кое-что по-лучше: линкер кросс-компилятора!mkostoevr wrote:Хочу написать маленький кросс компилятор.
- Attachments
-
-
Screenshot from 2020-12-20 15-25-21.png (292.76 KiB)Viewed 6153 times
-
Who is online
Users browsing this forum: No registered users and 4 guests