2013-02-02 3 views
3

У меня есть три вопроса:Компиляция C и сборка ASM в машинный код

  1. Какой компилятор можно использовать и как я могу использовать его для компиляции C исходного кода в машинный код ?
  2. Какой ассемблер можно использовать и как его использовать для сборки ASM до машинный код?
  3. (необязательно). Как вы порекомендовали бы разместить машинный код в правильных адресах (то есть машинный код загрузчика должен быть помещен в загрузочный сектор)?

Моя цель: Я пытаюсь сделать основную операционную систему. Это будет использовать лично сделанный загрузчик и ядро. Я также попытаюсь взять бит и куски из ядра Linux (а именно, драйверы) и интегрировать их в свое ядро. Я надеюсь создать 32-разрядную DOS-подобную операционную систему для обмена информацией с памятью на большинстве современных компьютеров. Я не думаю, что создам исполняемый формат для своей операционной системы, так как моя операционная система не будет достаточно динамичной, чтобы ее требовать.

My status: Я работаю на ноутбуке x86-64 Windows 8 с процессором Intel Celeron; Я считаю, что он использует безопасную загрузку. Я бы тестировал свою операционную систему на рабочем столе x86-64 с процессором Intel Core I3. У меня есть среднее понимание операционных систем и их методов. Я знаю теорию C, ASM и компьютер, необходимую для этого проекта. Я думаю, что также стоит отметить, что мне шестнадцать лет без формального образования по информатике.

Мое исследование: После поиска в Google, для которого обычно компилируется C, я нашел ответы, начиная от машинного кода, двоичного, простого двоичного, исходного двоичного, сборочного и перемещаемого объектного кода. Сборка, как я понимаю, обычно собирается в исполняемый файл в формате PE. Я слышал о компиляторах Cygwin, GCC C и MingW C. Что касается ассемблеров, я слышал о FASM, MASM и NASM. Я искал такие сайты, как OSDev и OSDever.

Что я пытался: Я попытался настроить GCC (кошмар) и создать кросс-компилятор (другой кошмар).

Заключение: Как вы можете судить, я не согласен с компиляторами, сборщиками и исполняемыми форматами. Пожалуйста, развейте мое невежество и ответьте на мои вопросы. Вероятно, это единственное, что мешает мне иметь ОС в моем резюме. Извините, я бы включил больше ссылок, но stackoverflow не позволил мне сделать больше двух. Благодаря тонну!

+7

Этот проект, вероятно, слишком далеко. Прямо сейчас вы должны снизить свои взгляды и работать над этим. –

+2

Все, что вам нужно, это простой GCC с обычной toolchain (в частности, ld), а не цепочка инструментов кросс-компилятора. См. Http://wiki.osdev.org/Bare_Bones – Mat

+0

«Какой компилятор я могу использовать и как его использовать для компиляции исходного кода C в машинный код?» - Любые. «Какой ассемблер можно использовать и как его использовать для сборки ASM для машинного кода?» - Любые. Цель этих инструментов, по определению, - это то, что вы описали. –

ответ

3

Во-первых, некоторые быстрые ответы на ваши три вопроса.

  1. Практически любой компилятор переводит код C в код сборки. Вот что компиляторы do. GCC и clang популярны и бесплатны.

    clang -S -o example.s example.c 
    
  2. Какой компилятор вы выбираете, вероятно, поддерживать сборку, а также, просто используя один и тот же драйвер компилятора.

    clang -o example.o example.s 
    
  3. Ваша документация линкер расскажет вам, как поставить конкретный код по конкретным адресам и так далее. Если вы используете GCC или clang, как описано выше, вы, вероятно, будете использовать ld(1). В этом случае прочитайте «скрипты компоновщика».

Далее, некоторые примечания:

  • Вам не нужен кросс-компилятор или настроить GCC самостоятельно. Вы работаете на машине Intel, генерируя код для машины Intel. Любое двоичное распределение clang или GCC, которое поставляется с вашим дистрибутивом linux, должно работать нормально.

  • Компиляторы C обычно компилируют код в сборку, а затем передают итоговую сборку на системный ассемблер, заканчивая машинным кодом. Машинный код, двоичный, обычный двоичный, raw-двоичный, все в основном синонимы.

  • Сгенерированный машинный код упакован в какой-то исполняемый формат файла, чтобы сообщить операционной системе хоста, как загрузить и запустить код. В Windows это PE, в Linux, это ELF, а в Mac OS X это Mach-O.

  • Вам не нужно создавать исполняемый формат для вашей ОС, но вы, вероятно, захотите использовать . ELF - довольно простой (и хорошо документированный) вариант.

И немного личной ноте, что я надеюсь не разочаровать вас слишком много - Если вы не очень знакомы с тем, как компиляторы, ассемблеры, сборщики, и все эти инструменты работают, ваш проект будет очень сложным и запутанным. Возможно, вы захотите начать с небольших проектов, чтобы получить «морские ноги», если можно так выразиться.

+0

Спасибо за отличный ответ! – user2035846

0

Во-первых, использовать что-то вроде виртуальной коробки для тестирования

Я думаю, что вы можете сделать несколько небольших шагов, получить удобную для написания кода C.

, а затем посмотрите, как работают загрузочные сектора на дисках (хорошо документированы в Интернете) также смотрите код других загрузчиков с открытым исходным кодом.

Затем посмотрите, как выполнить переключение задач. Его не так сложно писать. Вы даже можете написать большинство из них во время работы его под нормальной ОС, прежде чем пытаться поместить его в свою собственную ОС

С компиляторами обычно можно смешивать в ассемблерном инлайн обычно с asm { /* assembly code */ }

2

На первом «машинном коде» и «двоичные» являются синонимами. «Код объекта» - это своего рода промежуточный вид, который компоновщик будет преобразовывать в двоичный код в конце. Некоторые компиляторы C/C++ генерируют не непосредственно двоичный, а исходный код ассемблера, который они передают ассемблеру, который создает объектный код, а затем компоновщик, который делает окончательный двоичный файл. В большинстве случаев эти процессы прозрачны для пользователя. Вы подаете компилятор с помощью C/C++/Pascal/независимо от исходного кода и получаете двоичный файл на выходе.

FASM assembler, aka flatassembler - лучший ассемблер для разработки ОС. В FASM уже создано несколько ОС.

Это потому, что FASM является самокомпилируемым и очень легким переносным. Таким образом, в течение 2..3 дней вы можете перенести его в свою ОС, а затем ваша ОС станет самодостаточной - т. Е. Вы сможете скомпилировать программы из вашей ОС.

Еще одна хорошая особенность FASM заключается в том, что он не нуждается в компоновщике - он может генерировать непосредственно двоичные файлы в нескольких форматах.

Большое активное сообщество также очень важно. Для FASM имеется множество источников, в том числе для разработки ОС.

message board очень активен и является местом, где можно многому научиться.

2

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

Что ассемблере можно использовать и как я могу использовать его, чтобы собрать ASM в машинный код?

Один из nasm, yasm (в основном очень похожа nasm), fasm "MASM" т.е. ml64.exe, ml.exe и свободно доступны как часть инструментов Microsoft.

Из них я, вероятно, рекомендую либо nasm, либо yasm. Эта рекомендация полностью основана на личных предпочтениях - но по большому счету, широкий диапазон поддерживаемых платформ, а также использование синтаксиса Intel по умолчанию. Я попробую несколько и посмотрю, что вам нравится.

(необязательно). Как бы вы порекомендовали поместить машинный код в соответствующие адреса (то есть машинный код загрузчика должен быть помещен в загрузочный сектор)?

Ну, есть только один способ поместить загрузчик на правильный адрес для MBR - открыть диск в LBA 0 и писать ровно 512 байт там, заканчиваясь в 0x55AA. Промыть, затем закрыть. MBR обычно также содержит таблицу разделов, встроенную в нее - это как код, так и данные. Условный термин для этого материала - Von Neumann Architecture, который можно кратко суммировать, поскольку «программы и данные хранятся в одном месте». Действие BIOS на загрузку с диска будет состоять в том, чтобы прочитать первые 512 байт в память, проверить подпись и, если она соответствует, выполнить эту память (начиная с байта 0).

ОК, вот эти вопросы в сторону. Теперь я дам вам еще несколько заметок:

  • 512-байтов для загрузчика на самом деле недостаточно для чьего-либо использования. Таким образом, некоторые файловые системы содержат загрузочные секторы, и сам загрузчик просто загружает найденный в них код/​​данные. Это позволяет загружать большие объемы кода - достаточно, чтобы получить ядро. Например, grub содержит компоненты stage1, stage1_5 и stage2 в устаревшей версии.
  • Хотя большинство операционных систем требуют использования контейнера исполняемого формата, вы не нуждаетесь в .. На диске и в памяти исполняемый код представляет собой одну, две или три байтовые строки, называемые кодами операций. Вы можете прочитать the opcode reference или руководства для Intel/AMD, чтобы узнать, что означает шестнадцатеричное значение.Во всяком случае, вы можете выполнить прямое преобразование ассемблере двоичную с помощью NASM, как это:

    nasm -f bin input.asm -o output.asm 
    

    Который будет работать на 16, 32 или 64 бит ассемблере вполне счастливо, хотя результат, скорее всего, не будет выполняться. Единственное место, где это будет, - если вы явно используете директиву [bits 16] в своем коде, а также org 100h, то у вас есть программа MSDOS .com. К сожалению, это самый простой из существующих двоичных форматов: у вас есть только код и данные в одном большом компе, и это не должно превышать размер одного сегмента.

    Я чувствую, что это может справиться с этой точкой:

    я нашел ответы, начиная от машинного кода, двоичном, простого двоичного, необработанных двоичного, сборки и перемещаемого объектного кода.

    Ответ на вопрос, что сборочная сборка собирается - он собирает коды операций и адресов памяти, в зависимости от ассемблера. Это представлено в байтах, которые являются данными сами по себе. Вы можете прочитать их raw с шестнадцатеричным редактором, хотя есть несколько случаев, когда это строго необходимо. Я упоминаю адреса памяти, потому что некоторые коды операций управляют тем, как адреса памяти интерпретируются. Например, для перемещаемого объектного кода требуется, чтобы адреса не были жестко закодированы (вместо этого они интерпретируются как смещения из текущего местоположения).

    Сборка, как я понимаю, обычно собирается в исполняемый файл в формате PE.

    Это справедливо сказать ассемблер, из которого ваш C/C++ была получена компилируется опкодами, которые затем, вместе с чем-нибудь еще, чтобы быть включенным в программу (данные, ресурсы) хранятся в исполняемом формате , таких как PE. Обычно зависит от вашей ОС.

  • Если вы полностью ознакомились с OSDev Wiki, вы поймете, что сегментированная адресация является полной болью - стандартное и единственное использование сегментов в современных операционных системах - это определение четырех сегментов, охватывающих все адресное пространство - два сегмента данных в кольце 0 и 3, два сегмента кода в кольце 0 и 3.

  • Если вы еще не прочитали the OSDEV Wiki, вам необходимо. Я также рекомендовал бы JamesM's kernel tutorials, которые содержат практические советы по созданию ядра в C.

  • Если вы просто хотите делать плохие вещи в ядре DOS, вы на самом деле все равно можете без необходимости писать полное ядро ​​самостоятельно. Вы также должны иметь возможность переключать CPU в защищенный режим из DOS. Вам нужен FreeDOS и ассемблер по вашему выбору. Существует отличный учебник по terminate and stay resident, который в основном означает подключение подпрограммы прерывания, а затем редактирование себя из списка активных процессов в The Rootkit Arsenal. Возможно, для этого есть и учебные пособия в Интернете.

    Возможно, у меня возникнет соблазн рекомендовать сделать это как первое, просто чтобы привыкнуть к такого рода материалам низкого уровня.

  • Если вы просто хотите выставить ОС, вы можете настроить отладку ядра в Windows. WinDbg немного ... тайный, но как только вы привыкнете к нему, это имеет смысл.
  • Вы упомянули, что ваш ноутбук использует безопасную загрузку. Если это так, ваш ноутбук использует UEFI. Если вы хотите прочитать об этом, то UEFI spec на 100% гарантированно более скучно, чем ваша домашняя работа по математике, но я рекомендую скрыть его только для понимания целей и базовой среды.Важно иметь EFI SDK, который позволяет вам создавать приложения, совместимые с EFI (которые находятся в формате PE и существуют в разделе FAT32 на вашем диске), поэтому установка загрузчика EFI очень проста, даже если писать не так. Я должен был сделать честную рекомендацию, теперь я буду придерживаться MBR, поскольку эмуляция ОС с MBR намного проще, чем EFI на момент написания, и вы действительно хотите сделать это в той или иной форме VM на данный момент. Кроме того, я бы использовал существующий, как grub, так как загрузчики не так уж увлекательны.
  • Другие сказали это, и я скажу это: Вы абсолютно хотите сделать что-нибудь подобное в той или иной форме эмулятора или виртуальная машина. Вы совершите ошибку, гарантируете, и вы столкнетесь с тем, что не понимаете. В настоящее время в наших программах бесплатное программное обеспечение и программное обеспечение для виртуальных машин бесплатны, и некоторые из них, такие как BOCHS, расскажут вам, в чем причина данной ошибки, ловушки и т. д. Это очень полезно!
Смежные вопросы