Сделайте простой CRT0 в C или сборку

Я вернулся с C / C ++ и ASM и хочу немного поиграть с огнем. Я обнаружил, что когда вы компилируете и связываете код в исполняемый файл для Windows, он динамически связывается с некоторыми библиотеками, которые должны существовать на любом компьютере, где ожидается запуск этого приложения. Вы можете указать компилятор, чтобы он не связывался с ними, и для этого создайте свои собственные библиотеки.

Помимо этого (и, пожалуйста, поправьте меня, если я ошибаюсь во всем, что я здесь говорю), существует объектный файл, который всегда соблюдается и связывается с основным кодом нашего приложения. Это файл crt0.o (среда выполнения C), и, как я знаю, он подготавливает стек, получает argc и argv и вызывает основную функцию (и, возможно, другие вещи). Я также считаю, что это первый фрагмент кода, вызываемый системой при выполнении приложения.

Итак, я пытаюсь создать простой crt0.obj и связать его с простым объектным файлом C ++

int main(int argc, char** argv) {
return 0;
}

Я использую GCC и не хочу использовать стандартную библиотеку, поэтому моя команда выглядит так:

g++ -s -nostartfiles -nodefaultlibs -nostdlib testapp.cpp -o test.exe crt0.o

Я полагаю, что -nostartfiles директива — это то, что говорит компоновщику не встраивать файл crt0.o по умолчанию, поэтому он ожидает, что я дам каждое определение для любой функции и обработаю запуск приложения. Я немного запутался здесь.

В любом случае, я хочу создать очень простой объектный файл crt0, которого будет достаточно для GCC, чтобы создать мой исполняемый файл, и для системы, чтобы запустить его. Я знаю, что в Интернете есть много файлов кода (C и ASM), но я хочу написать свой собственный, чтобы узнать, как он работает. Больше, чем код, мне нужна небольшая справка о том, что он должен делать и как компилировать / ссылаться, чтобы этого добиться.
Если вы знаете любую полезную ссылку, которая также очень ценится.

Мои сомнения:
1. Как компилятор / ссылка создает окончательный файл из моего кода и среды выполнения C? Нужно ли вызывать основную функцию из crt0.o (используя директиву extern)? Когда я выполню g++ -s -nostartfiles -nodefaultlibs -nostdlib testapp.cpp -o test.exe Я получаю ошибку «* неопределенная ссылка на __main *». Основная функция определена в файле crt0.o? Странно, что если я изменю int main от int start Я не получаю никакой ошибки. Что это значит?
2. Какие основные операции должен содержать crt0 (например, получение аргументов командной строки, вызов main)?
3. Мой файл кода — это CPP, а crt0 — это фрагмент сборки внутри файла C (скомпилирован с GCC). Я опубликую некоторый «frankencode», который мне удалось создать из частей, которые я нашел и частично понял:

// crt0.c
__asm(".section .text\n"".global _start\n""_start:\n""mov $0, %ebp\n""push %ebp\n""mov %esp, %ebp\n""push %esi\n""push %edi\n""call _init\n""pop %edi\n""pop %esi\n""call main\n""movl %eax, %edi\n""call exit\n"".section .init\n"".global _init\n""_init:\n""push %ebp\n""mov %esp, %ebp\n"".section .fini\n"".global _fini\n""_fini:\n""push %ebp\n""mov %esp, %ebp\n");

4.) Итак, в этом файле я сделал несколько вызовов функций инициализации. Функции init и fini уже созданы (они выглядят как простые конструкторы и деструкторы, я не знаю). Существует также функция main, которая, я не знаю, как связана с функцией main .cpp. Я имею в виду, я должен импортировать это? я получил undefined reference ошибки для основной и выходной функций.
5.) Должен ли c0 иметь определенный формат или содержать определенную функцию, чтобы система нашла свое начало?

Ну, я не вижу трудностей сделать небольшой crt0 и заставить компилятор присоединить его к исполняемому файлу, но есть некоторые вещи, которые я не могу видеть правильно. Я надеюсь, что кто-нибудь может помочь мне совместить все это. Спасибо

4

Решение

У меня нет машины с Windows для тестирования, но это должны быть основные биты, которые вам нужны:

#// crt0.c
__asm(".section .text\n"".global _start\n""_start:\n""mov $0, %ebp\n""push %ebp\n""mov %esp, %ebp\n""call main\n""pop  %ebp\n""ret\n");

Редактировать: пусто __main:

__asm(".global __main\n""__main:\n""ret\n");
1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]