Обычно обработчик двойного отказа делают задачей, поскольку двойной отказ как раз и связан с кривым стеком системы (ну а у задачи для всех режимов, в т.ч. системы, свой набор стеков). Остальные же обработчики вызываются через шлюзы прерываний или ловушек -- совершенно обычным способом. Документацию на процессор читайте -- там всё подробно описано, со всеми нужными битами и т.п.
Всем доброго дня! Решил немного поэкспериментировать в связке ассемблера с языком высокого уровня. Как-то читал что можно связать NASM и GCC. У меня стоит Windows 7. Установил FASM и установил MinGW. Поставил FASM, потому что привык к нему (нравится мне его синтаксис) и вроде бы он умеет создавать объектные файлы (по крайней мере так написано). В общем я решил компилировать с помощью g++ (язык C++). Создал файл main.cpp с таким содержанием: Code (Text): struct Header { char name[20]; unsigned int age; }; void kernel(void) { Header header; header.age=22; } В начале я хотел компилировать через gcc (язык C), но у меня компилятор стал ругаться на вот это: Code (Text): struct Header { char name[20]; unsigned int age; }; Видимо в C структуры по другому описываются (я просто никогда не учил C) и поэтому решил использовать g++ (язык C++). И вот думаю, видимо не оправдано будет использование C++, так как не будет двух ключевых команд языка: new и delete. Собственно интересно, а какое прерывание они вызывают и что вообще происходит? А то если я их сейчас напишу, я даже представить не могу что произойдёт. Так что всё что мне и можно будет сделать, так это чтобы программа строго знала с чем работает, так как динамически я ничего не смогу создать. Далее я создал файл boot.asm с таким содержимым: Code (Text): format ELF use32 extrn kernel call kernel И я решил всё это соединить с помощью build.bat с таким вот содержимым: Code (Text): @echo on fasm boot.asm boot.o g++ -ffreestanding -c -o main.o main.cpp ld -Ttext 0x200000 -o 00.bin boot.o main.o objcopy 00.bin -O binary del boot.o del main.o pause Сейчас для меня не важно смещение значений через -Ttext, поэтому с этим числом я не заморачивался. Вот что мне выводится в ответ на запуск командного файла: Что я делаю не так? Собственно даже если всё и получится, то gcc/g++ будут компилировать 32-битный код, следовательно мне сначала на ассемблере нужно будет перейти в защищённый режим и затем уже прыгнуть на C/C++ 32-битный код. А можно ли как-то задать gcc/g++, чтобы он генерировал 16/64-битный код? Например описывать системные структуры и сам переход в защищённый режим на языке высокого уровня. Разумеется что первым делом у меня будет ассемблерный загрузчик boot, который загрузит остальные сектора, а уже на них будет в начале 16-битный скомпилированный с языка высокого уровня (C/C++) код. Такой вариант был бы совсем не плох для ознакомления. Собственно когда я зашёл в документацию по FASM, там было сказано что можно получить следующие форматы файлов: - MZ executable; - Portable Executable; - Common Object File Format; - Executable and Linkable Format. Но я не знаю какой из них нужен мне для линковки. Не хочется из-за этого переходить на NASM. Что касается C или C++, то на сколько я знаю, на C++ вроде бы ещё ни одна операционная система не была написана. Да это и понятно, нет надобности в этих классах. Да и проблемы с new/delete. Ну а собственно что происходит если вызвать new/delete в 32-битном бинарном коде?
Родным для ГЦЦ является ЕЛФ, его и использовать. А библиотеки все придётся писать свои (ну, кроме математики разве что), поскольку они увязываются с осью, в которой программа должна выполняться, а здесь оси нет.
С g++ на gcc перешёл. Достаточно было так написать: Code (Text): struct Header { char name[20]; unsigned int age; }; void kernel(void) { unsigned int i=0; struct Header a; for(i=0;i<20;i++) a.name[i]=0; a.age=22; } Не знал что при объявлении нужно использовать слово struct. Ну а с другими вопросами поможете?
про декорацию имён слышали??? Если хотите пользоваться именем kernel а не его декорированным братом, то юзайте конструкцию вроде: extrn kernel as "_kernel@0" За тем как использовать extrn и as - в хэлп фасма. За тем как имена декорируются - в гугл
Честно, ничего не понял. Пробовал различные варианты, и даже так: Code (Text): format ELF use32 extrn 'kernel' as _kernel kernel = PLT _kernel call _kernel Не помогает.
Это что, вот так вот и всё? Code (Text): format ELF use32 extrn '_kernel' as kernel _kernel = PLT kernel call kernel
Он теперь и так компилирует: Code (Text): format ELF use32 extrn '_kernel' as kernel call kernel И это правильно?
s3dworld #430 Вроде правильный Точно помню, что С добавляет _ перед именем, а вот добавляет ли он @ после не помню.... Если добавляет, то надо писать extrn '_kernel@0' as kernel или даже так правильнее будет extrn '_kernel@0' as kernelWORD
iZzz32 А у гнутого с? Он же гнутый использует.... Да и вообще... можно хексвьювером посмотреть имена... уж если на это пошло....
Странно, если искать в гугле мою подпись, то вторым номером выходит тред с названием "Клерк", а всё остальные - это религиозная муть всякая.... Мистика!
Проверил, gcc добавляет к именам функций символ _ в начале названия функции. Думаю эта проблема решена. Вроде бы даже нашёл как создавать 16-битный код: Code (Text): asm(".code16\n"); struct Header { char name[20]; unsigned int age; }; void kernel() { unsigned int i=0; struct Header a; for(i=0;i<20;i++) a.name[i]=0; a.name[0]='S'; a.name[1]='e'; a.name[2]='r'; a.name[3]='g'; a.name[4]='e'; a.name[5]='i'; a.name[6]='!'; a.age=22; } На деле не проверял, но прочитал что именно так он создаёт 16-битный код. Теперь далее перейдём к моему ассемблерному коду: Code (Text): format ELF use16 extrn '_kernel' as kernel call kernel hlt; Разумеется такой код не будет работать при включения компьютера, так как я не поставил метку загрузочного сектора. И вообще эти первые 512 байт у меня будут грузить другие сектора и уже в других будет ассемблерный код. То есть я сделаю так: boot.asm, perehod.asm, main.c. FASM займётся boot.asm и perehod.asm, а GCC займётся main.c. Потом с помощью LD они будут объединены в Test.img. Но пока вот смотрите что он мне пишет на счёт компиляции boot.asm: То есть ошибка с адресом. Ну и как мне тогда тут быть, как заставить 16-битный код ассемблера прыгнуть, вроде бы, на 16-битный код C?
Опишу Вам мою ситуацию. Создал в папке файл boot.asm: Code (Text): format ELF use16 org 0x7C00 hlt rb 510-($-$$) db 0x55,0xAA Компилирую, линкую и превращаю в бинарник: Code (Text): fasm boot.asm boot.o ld -o Test.bin boot.o objcopy Test.bin -O binary На выходе получаю файл Test.bin с размером в 8212 байт. Странно, я думал что будет 512 байт, ну да ладно. Открываю его в hex-редакторе: С самого начала идёт: А вот начиная со смещения 0x1000 (то есть 4096) идёт: И далее снова 0x00. Почему так? Я думал я получу 512 байт.
Code (Text): format ELF Зачем для бутлоадера то? Просто Code (Text): org 0x7C00 Вы не знаете более-менее хорошо ни один язык. Какая ось? Ну если вы её на ActionScript собрались писать, то пожалуйста. Повторю в сотый раз:"Базовые знания!!!".
s3dworld Вы хоть читаете, что он вам пишет? Русским же языком написано... не указан размер! Попробуйте так Ну, или WORD не знаю какой размер там надо. Кроме виндовс ни под что другое не писал. А вообще-то мне не понятна ваша логика. Зачем писать в фасм и линковать с чем-то другим? Просто пишите загрузчик на фасм (в бин формате, насколько я понимаю). Затем, когда всё, что вам нужно сделано загружаете в память модуль написанный на чём угодно и в каком угодно для вас формате. Переходите в какой вам угодно режим и передаёте управление в загруженный модуль.... Вы бы перед тем как браться изучили бы исходники (естественно, я не про весь код, а только про загрузчик) виндовс/*никс/РеактОс или даже КалибриОС/МинуэтОС (эти вообще почти целиком написаны на фасме!). И ещё, есть книга, в которой рассматривается создание/устройство ОС. И в качестве примера там МИНИКС. Ищите да обрящете! Тут было вполне логичное предложение относительно матчасти....