Несколько вопросов начинающего

Discussion in 'WASM.BEGINNERS' started by s3dworld, Oct 6, 2010.

  1. SII

    SII Воин против дзена

    Blog Posts:
    0
    Вроде нет, но я бы создал, заполнил правильным образом и всё такое. Мешать он точно никому не будет.
     
  2. s3dworld

    s3dworld Сергей

    Blog Posts:
    0
    SII
    Спасибо! Только тогда мне нужно обработчики прерываний описывать не как задачи. Так?
     
  3. SII

    SII Воин против дзена

    Blog Posts:
    0
    Обычно обработчик двойного отказа делают задачей, поскольку двойной отказ как раз и связан с кривым стеком системы (ну а у задачи для всех режимов, в т.ч. системы, свой набор стеков). Остальные же обработчики вызываются через шлюзы прерываний или ловушек -- совершенно обычным способом. Документацию на процессор читайте -- там всё подробно описано, со всеми нужными битами и т.п.
     
  4. s3dworld

    s3dworld Сергей

    Blog Posts:
    0
    Всем доброго дня!

    Решил немного поэкспериментировать в связке ассемблера с языком высокого уровня. Как-то читал что можно связать NASM и GCC. У меня стоит Windows 7. Установил FASM и установил MinGW. Поставил FASM, потому что привык к нему (нравится мне его синтаксис) и вроде бы он умеет создавать объектные файлы (по крайней мере так написано).

    В общем я решил компилировать с помощью g++ (язык C++). Создал файл main.cpp с таким содержанием:

    Code (Text):
    1. struct Header
    2. {
    3.     char name[20];
    4.     unsigned int age;
    5. };
    6.  
    7. void kernel(void)
    8. {
    9.     Header header;
    10.    
    11.     header.age=22;
    12. }
    В начале я хотел компилировать через gcc (язык C), но у меня компилятор стал ругаться на вот это:

    Code (Text):
    1. struct Header
    2. {
    3.     char name[20];
    4.     unsigned int age;
    5. };
    Видимо в C структуры по другому описываются (я просто никогда не учил C) и поэтому решил использовать g++ (язык C++). И вот думаю, видимо не оправдано будет использование C++, так как не будет двух ключевых команд языка: new и delete. Собственно интересно, а какое прерывание они вызывают и что вообще происходит? А то если я их сейчас напишу, я даже представить не могу что произойдёт.

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

    Далее я создал файл boot.asm с таким содержимым:

    Code (Text):
    1. format ELF
    2. use32
    3. extrn kernel
    4.  
    5. call kernel
    И я решил всё это соединить с помощью build.bat с таким вот содержимым:

    Code (Text):
    1. @echo on
    2. fasm boot.asm boot.o
    3. g++ -ffreestanding -c  -o main.o main.cpp
    4. ld -Ttext 0x200000 -o 00.bin boot.o main.o
    5. objcopy 00.bin -O binary
    6. del boot.o
    7. del main.o
    8. 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-битном бинарном коде?
     
  5. SII

    SII Воин против дзена

    Blog Posts:
    0
    Родным для ГЦЦ является ЕЛФ, его и использовать. А библиотеки все придётся писать свои (ну, кроме математики разве что), поскольку они увязываются с осью, в которой программа должна выполняться, а здесь оси нет.
     
  6. s3dworld

    s3dworld Сергей

    Blog Posts:
    0
    С g++ на gcc перешёл. Достаточно было так написать:

    Code (Text):
    1. struct Header
    2. {
    3.     char name[20];
    4.     unsigned int age;
    5. };
    6.  
    7. void kernel(void)
    8. {
    9.     unsigned int i=0;
    10.     struct Header a;
    11.    
    12.     for(i=0;i<20;i++) a.name[i]=0;
    13.     a.age=22;
    14. }
    Не знал что при объявлении нужно использовать слово struct. Ну а с другими вопросами поможете?
     
  7. Z3N

    Z3N New Member

    Blog Posts:
    0
    про декорацию имён слышали???

    Если хотите пользоваться именем kernel а не его декорированным братом, то юзайте конструкцию вроде:

    extrn kernel as "_kernel@0"

    За тем как использовать extrn и as - в хэлп фасма.
    За тем как имена декорируются - в гугл
     
  8. s3dworld

    s3dworld Сергей

    Blog Posts:
    0
    Честно, ничего не понял. Пробовал различные варианты, и даже так:

    Code (Text):
    1. format ELF
    2. use32
    3. extrn 'kernel' as _kernel
    4. kernel = PLT _kernel
    5.  
    6. call _kernel
    Не помогает.
     
  9. s3dworld

    s3dworld Сергей

    Blog Posts:
    0
    Это что, вот так вот и всё?

    Code (Text):
    1. format ELF
    2. use32
    3. extrn '_kernel' as kernel
    4. _kernel = PLT kernel
    5.  
    6. call kernel
     
  10. s3dworld

    s3dworld Сергей

    Blog Posts:
    0
    Он теперь и так компилирует:

    Code (Text):
    1. format ELF
    2. use32
    3. extrn '_kernel' as kernel
    4.  
    5. call kernel
    И это правильно?
     
  11. Z3N

    Z3N New Member

    Blog Posts:
    0
    s3dworld

    прочитай про extrn!!!!
     
  12. Z3N

    Z3N New Member

    Blog Posts:
    0
    s3dworld
    #430
    Вроде правильный

    Точно помню, что С добавляет _ перед именем, а вот добавляет ли он @ после не помню....

    Если добавляет, то надо писать

    extrn '_kernel@0' as kernel

    или даже так правильнее будет

    extrn '_kernel@0' as kernel:lol: WORD
     
  13. iZzz32

    iZzz32 Sergey Sfeli

    Blog Posts:
    0
    Z3N, @ при stdcall/32-bit ms fastcall появляется.
     
  14. Z3N

    Z3N New Member

    Blog Posts:
    0
    iZzz32
    А у гнутого с? Он же гнутый использует....
    Да и вообще... можно хексвьювером посмотреть имена... уж если на это пошло....
     
  15. Z3N

    Z3N New Member

    Blog Posts:
    0
    Странно, если искать в гугле мою подпись, то вторым номером выходит тред с названием "Клерк", а всё остальные - это религиозная муть всякая.... Мистика!
     
  16. s3dworld

    s3dworld Сергей

    Blog Posts:
    0
    А gcc/g++ может генерировать 16-битный код, чтобы потом с помощью ld собрать всё в один модуль?
     
  17. s3dworld

    s3dworld Сергей

    Blog Posts:
    0
    Проверил, gcc добавляет к именам функций символ _ в начале названия функции. Думаю эта проблема решена. Вроде бы даже нашёл как создавать 16-битный код:

    Code (Text):
    1. asm(".code16\n");
    2.  
    3. struct Header
    4. {
    5.     char name[20];
    6.     unsigned int age;
    7. };
    8.  
    9. void kernel()
    10. {
    11.     unsigned int i=0;
    12.     struct Header a;
    13.    
    14.     for(i=0;i<20;i++) a.name[i]=0;
    15.    
    16.     a.name[0]='S';
    17.     a.name[1]='e';
    18.     a.name[2]='r';
    19.     a.name[3]='g';
    20.     a.name[4]='e';
    21.     a.name[5]='i';
    22.     a.name[6]='!';
    23.    
    24.     a.age=22;
    25. }
    На деле не проверял, но прочитал что именно так он создаёт 16-битный код. Теперь далее перейдём к моему ассемблерному коду:

    Code (Text):
    1. format ELF
    2. use16
    3. extrn '_kernel' as kernel
    4.  
    5. call kernel
    6. hlt;
    Разумеется такой код не будет работать при включения компьютера, так как я не поставил метку загрузочного сектора. И вообще эти первые 512 байт у меня будут грузить другие сектора и уже в других будет ассемблерный код. То есть я сделаю так: boot.asm, perehod.asm, main.c. FASM займётся boot.asm и perehod.asm, а GCC займётся main.c. Потом с помощью LD они будут объединены в Test.img.

    Но пока вот смотрите что он мне пишет на счёт компиляции boot.asm:

    То есть ошибка с адресом. Ну и как мне тогда тут быть, как заставить 16-битный код ассемблера прыгнуть, вроде бы, на 16-битный код C?
     
  18. s3dworld

    s3dworld Сергей

    Blog Posts:
    0
    Опишу Вам мою ситуацию.

    Создал в папке файл boot.asm:

    Code (Text):
    1. format ELF
    2. use16
    3. org 0x7C00
    4.  
    5. hlt
    6.  
    7. rb 510-($-$$)
    8. db 0x55,0xAA
    Компилирую, линкую и превращаю в бинарник:

    Code (Text):
    1. fasm boot.asm boot.o
    2. ld -o Test.bin boot.o
    3. objcopy Test.bin -O binary
    На выходе получаю файл Test.bin с размером в 8212 байт. Странно, я думал что будет 512 байт, ну да ладно. Открываю его в hex-редакторе:

    С самого начала идёт:

    А вот начиная со смещения 0x1000 (то есть 4096) идёт:

    И далее снова 0x00.

    Почему так? Я думал я получу 512 байт.
     
  19. Igor1024

    Igor1024 Васил Троянов Боянов (Azis)

    Blog Posts:
    0
    Code (Text):
    1. format ELF
    Зачем для бутлоадера то? Просто
    Code (Text):
    1. org 0x7C00
    Вы не знаете более-менее хорошо ни один язык.
    Какая ось? Ну если вы её на ActionScript собрались писать, то пожалуйста.
    Повторю в сотый раз:"Базовые знания!!!".
     
  20. Z3N

    Z3N New Member

    Blog Posts:
    0
    s3dworld
    Вы хоть читаете, что он вам пишет? Русским же языком написано... не указан размер!

    Попробуйте так
    Ну, или WORD не знаю какой размер там надо. Кроме виндовс ни под что другое не писал.

    А вообще-то мне не понятна ваша логика. Зачем писать в фасм и линковать с чем-то другим? Просто пишите загрузчик на фасм (в бин формате, насколько я понимаю). Затем, когда всё, что вам нужно сделано загружаете в память модуль написанный на чём угодно и в каком угодно для вас формате. Переходите в какой вам угодно режим и передаёте управление в загруженный модуль....

    Вы бы перед тем как браться изучили бы исходники (естественно, я не про весь код, а только про загрузчик) виндовс/*никс/РеактОс или даже КалибриОС/МинуэтОС (эти вообще почти целиком написаны на фасме!).

    И ещё, есть книга, в которой рассматривается создание/устройство ОС. И в качестве примера там МИНИКС. Ищите да обрящете! Тут было вполне логичное предложение относительно матчасти.... ;)