Я вернулся с 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 и заставить компилятор присоединить его к исполняемому файлу, но есть некоторые вещи, которые я не могу видеть правильно. Я надеюсь, что кто-нибудь может помочь мне совместить все это. Спасибо
У меня нет машины с 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");
Других решений пока нет …