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

Тема в разделе "WASM.BEGINNERS", создана пользователем s3dworld, 6 окт 2010.

  1. s3dworld

    s3dworld Сергей

    Публикаций:
    0
    Регистрация:
    16 мар 2010
    Сообщения:
    387
    Адрес:
    Ртищево
    KIV

    Код (Text):
    1. KERNEL_CODE64_SELECTOR = 1 shl 3
    Тут 1 shl 3 будет равно 8?

    Я всё равно не понял как оно это делает. Ведь shl это же сдвиг влево.
     
  2. KIV

    KIV Member

    Публикаций:
    0
    Регистрация:
    16 июл 2009
    Сообщения:
    231
    В данном контексте это не команда ассемблера, а команда компилятора
    всё равно что:
    mov eax, 1 * 8
    очевидно, что получиться mov eax, 8
    а тут mov eax, 1 shl 8
     
  3. SII

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

    Публикаций:
    0
    Регистрация:
    31 окт 2007
    Сообщения:
    1.483
    Адрес:
    Подмосковье
    s3dworld
    Нужно внимательно читать справочники и вникать в то, что там написано :) И кстати, думать головой постоянно, поскольку в официальных руководствах тоже встречаются ошибки, противоречия и недосказанности.

    Ну и простой совет: не пытаться сразу охватить всё. Если хорошо разобрались с работой в реальном режиме (в частности, чётко понимаете, что представляют из себя тамошние сегменты и почему к одной и той же физической ячейке памяти можно из программы обращаться по разным адресам), тогда переходите к защищённому. Разберётесь с ним -- начинайте вникать в страничный механизм. И лишь после этого беритесь за 64-разрядный режим.
     
  4. s3dworld

    s3dworld Сергей

    Публикаций:
    0
    Регистрация:
    16 мар 2010
    Сообщения:
    387
    Адрес:
    Ртищево
    SII
    Хороший совет! Почему в R-MODE через разные линейные адреса можно попасть на одну и ту же ячейку памяти - я разобрался.

    СЕГМЕНТ - это значение умноженное на 16 (0x10);
    СМЕЩЕНИЕ - смещение.

    И получается что: уже умноженное значение сегмента на 16 (0x10) + смещение.

    Но я всё равно не понял что значит shl((
     
  5. SII

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

    Публикаций:
    0
    Регистрация:
    31 окт 2007
    Сообщения:
    1.483
    Адрес:
    Подмосковье
    shl -- сдвиг влево. А Вы запутались из-за того, что не различаете операции, выполняемые транслятором во время трансляции программы, и операциями, выполняемыми непосредственно при выполнении программы.

    В примере, приведённом выше, было написано:

    Код (Text):
    1. KERNEL_CODE64_SELECTOR = 1 shl 3
    Это абсолютно то же самое, что:

    Код (Text):
    1. KERNEL_CODE64_SELECTOR = 8
    Лично я, кстати, записал бы именно вторым способом, но это уже вопрос стиля.

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

    А вот когда записана ассемблерная команда:

    Код (Text):
    1. shl  ax, 1
    она не будет выполнена во время трансляции; вместо этого транслятор переведёт её в соответствующий машинный код. Она будет выполнена лишь во время выполнения программы и сделает то, что положено: сдвинет влево на 1 разряд содержимое регистра AX.
     
  6. s3dworld

    s3dworld Сергей

    Публикаций:
    0
    Регистрация:
    16 мар 2010
    Сообщения:
    387
    Адрес:
    Ртищево
    SII
    Спасибо! Теперь стало понятно. Будем считать что это макрос.

    А действительно ли, что в защищённом режиме (скорее всего и в длинном режиме) не будут доступны функции (прерывания) BIOS?

    А то я прочитал что в таких случаях нужно либо писать самому драйвера на устройства (ой, мама, помоги!), либо использовать виртуальный режим 8086 (опять к динозаврам). Так как же на самом деле можно и как делают на практике?
     
  7. max7C4

    max7C4 New Member

    Публикаций:
    0
    Регистрация:
    17 мар 2008
    Сообщения:
    1.203
    s3dworld
    Вы сами отвечаете на свой вопрос, т.е. надо попросить маму помочь!
     
  8. s3dworld

    s3dworld Сергей

    Публикаций:
    0
    Регистрация:
    16 мар 2010
    Сообщения:
    387
    Адрес:
    Ртищево
    max7C4
    Так оборудования специфические. Это ведь BIOS использует общий функционал (стандарт какой-нибудь). Скажем переключить режим работы видеоадаптера и вывести точку в указанную позицию...я даже не представляю как это делается (конечно догадываюсь что пересылкой данных в порта и чтение данных из портов, но в какие).
     
  9. max7C4

    max7C4 New Member

    Публикаций:
    0
    Регистрация:
    17 мар 2008
    Сообщения:
    1.203
    s3dworld
    Биос не использует каких-то строгих стандартов. Он заточен только под те железяки, где сам находится, не более и не менее. Драйвера делают тоже самое. Они используя системный универсальный интерфейс для своего устройства, будучи заточенными под взаимодействие только с ними (устройством и универсальным системным интерфейсом), осуществляют передачу информации из устройства в систему и наоборот.
    {ADD}
    Драйвера можно сравнить с переводчиками с языка системы на язык своего устройства и наоборот.
     
  10. SII

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

    Публикаций:
    0
    Регистрация:
    31 окт 2007
    Сообщения:
    1.483
    Адрес:
    Подмосковье
    s3dworld
    А вот не надо считать, что это макрос. Вещи надо считать тем, что они есть, иначе неизбежно запутаетесь.

    Действительно. Поэтому загрузчики ОС без конца прыгают между реальным и защищённым или же используют V86. В общем, сплошные костыли.
     
  11. KIV

    KIV Member

    Публикаций:
    0
    Регистрация:
    16 июл 2009
    Сообщения:
    231
    Кстати, в длинном режиме отказались от V86.
    Нет. Эта конструкция аналогична:
    Код (Text):
    1. #define KERNEL_CODE64_SELECTOR 8
    Или если вы пишите в Си a = 1 shl 3 копилятор сам вычислит 1 shl 3 и сделает уже команду a = 8, а не заставит программу каждый раз вычислять 1 shl 3.
     
  12. s3dworld

    s3dworld Сергей

    Публикаций:
    0
    Регистрация:
    16 мар 2010
    Сообщения:
    387
    Адрес:
    Ртищево
    Мне вот интересно, а в нестандартных компьютерах (экран 16:9 или же экран 16:10, да и вообще в ноутбуках) ведь размер видео-странички при включении компьютера не такой как у обычных компьютеров с 4:3?

    То есть если я напишу программу которая зальёт всю мою видео-страничку, то при запуске этой де программы на другом компьютере, она возможно зальёт не всю страничку?
     
  13. SII

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

    Публикаций:
    0
    Регистрация:
    31 окт 2007
    Сообщения:
    1.483
    Адрес:
    Подмосковье
    Совместимость обеспечивается БИОСом и самим железом. А ёмкость видеостраницы зависит от видеорежима, а не от отношения сторон монитора.
     
  14. s3dworld

    s3dworld Сергей

    Публикаций:
    0
    Регистрация:
    16 мар 2010
    Сообщения:
    387
    Адрес:
    Ртищево
    SII
    То есть по умолчанию везде идёт 80 на 25?
     
  15. max7C4

    max7C4 New Member

    Публикаций:
    0
    Регистрация:
    17 мар 2008
    Сообщения:
    1.203
    s3dworld
    Столько сколько захочет биос. На моих материнках и ноутбуке, если включить графическую заставку bios, он может забыть переключить видюху в режим 80*25
     
  16. s3dworld

    s3dworld Сергей

    Публикаций:
    0
    Регистрация:
    16 мар 2010
    Сообщения:
    387
    Адрес:
    Ртищево
    max7C4
    Как узнать какой режим включен (какое разрешение)?
     
  17. SII

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

    Публикаций:
    0
    Регистрация:
    31 окт 2007
    Сообщения:
    1.483
    Адрес:
    Подмосковье
    Это уже ошибка в БИОСе -- правда, по нынешним временам безобидная (вряд ли кто-то там запускает ДОС, да и она сама вроде как устанавливает себе режим соответствующим вызовом).

    Но, поскольку ошибки возможны, лучше всегда включать нужный режим, а потом уже обращаться к видеопамяти.
     
  18. s3dworld

    s3dworld Сергей

    Публикаций:
    0
    Регистрация:
    16 мар 2010
    Сообщения:
    387
    Адрес:
    Ртищево
    Что-то я запутался. Пишу на FASM. Вот файл main.asm:

    Код (Text):
    1. use16                           ; Используем 16-битный код
    2.  
    3. org 0x7C00                      ; Смещение
    4.  
    5. ; --------------------------------------------------------------------------
    6. ; Начало 16-битного кода
    7. ; --------------------------------------------------------------------------
    8. code16:
    9.     call InitScreen             ; Инициализация экрана
    10.     call ClearScreen            ; Очищаем весь экран
    11.    
    12.     mov DL,4
    13.     mov DH,4
    14.     call SetCursorPos
    15.    
    16.     mov BL,00000100b
    17.     call DrawText
    18.    
    19.     call LoopProcessor          ; Подвешиваем процессор
    20.  
    21. ; --------------------------------------------------------------------------
    22. ; Подвешивание процессора
    23. LoopProcessor:
    24.     jmp LoopProcessor           ; Переходим на эту же инструкцию
    25. ret
    26. ; --------------------------------------------------------------------------
    27.  
    28. include "BIOS.asm"
    29.  
    30. ; --------------------------------------------------------------------------
    31. ; Начало 16-битных данных
    32. ; --------------------------------------------------------------------------
    33. data16:
    34.     text1 db "Hello my friend!",0x00
    Никак не могу понять как реализовать передачу адреса где находится первый байт строки и вообще вывод этой строки через смещение. Вот тут я начал делать, но не смог (BIOS.asm):

    Код (Text):
    1. ; --------------------------------------------------------------------------
    2. ; Инициализация экрана
    3. ; --------------------------------------------------------------------------
    4. InitScreen:
    5.     mov AH,0x00                 ; Код функции
    6.     mov AL,0x03                 ; Код режима (80x25x16)
    7.    
    8.     int 0x10                    ; Вызываем прерывание BIOS
    9. ret
    10.  
    11. ; --------------------------------------------------------------------------
    12. ; Очистка экрана
    13. ; --------------------------------------------------------------------------
    14. ClearScreen:
    15.     mov AH,0x09                 ; Код функции
    16.     mov AL,' '                  ; Выводимый символ
    17.     mov BH,0x00                 ; Номер страницы
    18.     mov BL,00010000b            ; Атрибуты
    19.     mov CX,2000                 ; Количество повторений
    20.    
    21.     int 0x10                    ; Вызываем прерывание BIOS
    22. ret
    23.  
    24. ; --------------------------------------------------------------------------
    25. ; Установка положения курсора
    26. ; DH - номер строки
    27. ; DL - номер столбца
    28. ; --------------------------------------------------------------------------
    29. SetCursorPos:
    30.     mov AH,0x02                 ; Код функции
    31.     mov BH,0x00                 ; Номер страницы
    32.    
    33.     int 0x10                    ; Вызываем прерывание BIOS
    34. ret
    35.  
    36. ; --------------------------------------------------------------------------
    37. ; Вывод текста
    38. ; BL - атрибуты текста
    39. ; --------------------------------------------------------------------------
    40. DrawText:
    41.     mov AH,0x09                 ; Код функции
    42.     mov BH,0x00                 ; Номер страницы
    43.     mov CX,1                    ; Количество повторений
    44.  
    45.     DrawTextLoop:
    46.         ;mov AL,[DS:0x0000+DI]
    47.         cmp AL,0x00
    48.         jz DrawTextExit
    49.         int 0x10                    ; Вызываем прерывание BIOS
    50.         inc DI
    51.     jmp DrawTextLoop
    52.    
    53.     DrawTextExit:
    54. ret
    Подскажите, как это реализовать?
     
  19. KIV

    KIV Member

    Публикаций:
    0
    Регистрация:
    16 июл 2009
    Сообщения:
    231
    Я делаю это так:
    Код (Text):
    1. write_str:
    2.     push ax si
    3.     mov ah, 0x0E
    4. @@:
    5.     lodsb
    6.     test al, al
    7.     jz @f
    8.     int 0x10
    9.     jmp @b
    10. @@:
    11.     pop si ax
    12.     ret
    13. ...
    14.     mov si, hello_msg
    15.     call write_str
    16. ...
    17. hello_msg db "Hello world!",13,10,0
    При этом не стоит забывать инициализировать DS и прочие сег. регистры, потому что при старте там вполне может быть не 0:
    Код (Text):
    1. org 0x7C00
    2.     jmp 0:@f
    3. @@:
    4.     mov ax, cs
    5.     mov ds, ax
    6.     mov es, ax
    7.     sti ; Прерывания изначально запрещены - их надо разрешить
    8.     ... тут уже собственно код твоей программы ...
     
  20. SII

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

    Публикаций:
    0
    Регистрация:
    31 окт 2007
    Сообщения:
    1.483
    Адрес:
    Подмосковье
    s3dworld
    Не совсем ясно, в чём у Вас проблема. Я, правда, не знаток синтаксиса ФАСМ (не пишу на нём, поскольку он мне не нравится), но вроде бы считывание памяти по заданному адресу (у Вас, судя по всему, он находится в DS:lol: I) в AL там будет выглядеть так: MOV AL, [DI] (сегмент данных подразумевается во всех обращениях к операндам, за несколькими исключениями: если один из компонентов адреса операнда находится в BP/EBP или ESP (но не к SP -- такого быть попросту не может), тогда идёт обращение к стеку; в строковых операциях операнд-источник находится в DS:dntknw:E)SI, а приёмник -- в ES:dntknw:E)DI; вроде ещё какое-то исключение было).