Аппаратный ввод-вывод в текстовом режиме VGA в старой сборке dos Проблема

Прочитав хотя бы первые 3 или 4 главы примерно 4 разных книг по программированию на ассемблере, я дошел до стадии, когда я могу поместить «Hello World» на консоль dosbox с помощью MASM 6.11. Представьте себе мой восторг !!

В первой версии моей программы использовалась функция DOS 13h. Вторая версия моей программы использовала функцию BIOS 10h

Теперь я хочу сделать третью версию, используя прямой аппаратный вывод. Я прочитал части книг, в которых объясняется, что экран разделен на 80x25 на мониторах VGA (не беспокоился об обнаружении CGA и всем остальном, поэтому моя программа использует адрес памяти 0B800h для цветного VGA, потому что DOSBox великолепен и все, и мое желание перейти на Win Assembler когда-то до того, как мне исполнится 90 лет). Я читал, что каждый символ на экране оборудования составляет 2 байта (1 для атрибута и один для самого символа, поэтому у вас 80x25x2 = 4000 байтов). Нечетные байты описывают атрибут, а четные байты - символ ASCII.

Но моя проблема вот в чем. Как бы я ни старался, я не могу заставить свою программу выводить простую черно-белую (что является просто атрибутом, я полагаю, я могу достаточно легко изменить это) строку (которая представляет собой просто массив байтов) в 5 строках сверху экрана и 20 символов от левого края (это просто количество пустых символов от нулевого индекса длиной 4000 байтов). (если мой расчет верен, это 5x80 = 400 + 20 = 420x2 = 840 - это начальная позиция моей строки в массиве из 4000 байтов)

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

Я пробовал поискать в Интернете этот, казалось бы, простой вопрос, но не могу найти решения. Есть ли кто-нибудь, кто раньше программировал в DOS и на ассемблере x86, и мог бы сказать мне, как сделать эту простую небольшую программу, не используя функции BIOS или DOS, а только с оборудованием.

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

Я пытаюсь создать библиотеку подпрограмм, которая упростит освоение ассемблера, чтобы людям не приходилось работать, хотя все от 3 до 6 глав в 10 книгах теории, по сути, снова и снова объясняют одни и те же вещи, когда на самом деле все, что нужно, достаточно чтобы знать, как получить некоторый результат, присвоить значения переменным, получить некоторый ввод и выполнить некоторые циклы и решения. Теория может появиться позже, и к тому времени, когда они дойдут до циклов и решений, большинство людей уже сделают достаточно ассемблера, чтобы иметь всю теорию в любом случае. Я верю, что сборку следует обучать не иначе, как любому другому языку, начиная с простой программы hello world, а затем получая ввод и т. Д. Я хочу сделать это возможным. Но эй, я только новичок, может быть, мои таланты изменятся, когда я узнаю больше.

Еще одно замечание: я точно знаю, что проблема НЕ в DOSBox, так как у меня очень старый компьютер с истинной MS-DOS V6.2, и программа все еще не работает (но дает почти идентичный результат). Фактически, DOSBox запускает некоторые из моих старых программ даже лучше, чем True dos. Рабочий стол Gem является одним из примеров. Просто хотел очистить это, прежде чем люди попытаются предположить, что это проблема с эмулятором. Не может быть, не с такими простыми программами. Не боюсь, проблема в том, что мой маленький мозг не полностью понимает, что нужно.

Может кто-нибудь там, пожалуйста, помогите !!


Ниже представлена ​​программа, которую я использовал (MASM 6.1 под DOSBox на Win 7 64-бит). Он использует BIOS Intrrupt 10h, функцию 13h, подфункцию 0. Я хочу сделать то же самое, используя прямой аппаратный ввод-вывод.


.model small
.stack
.data           ;part of the program containing data
    ;Constants - None
    ;Variables
    MyMsg   db    'Hello World'

.code
Main:
GetAddress:
    mov ax,@data        ;Gets address of data segment
    mov es,ax           ;Loads segment address into es regrister
    mov bp,OFFSET MyMsg ;Load Offset into DX

SetAttributes:
    mov bl,01001111b    ;BG/FG Colour attributes
    mov cx,11           ;Length of string in data segment

SetRowAndCol:
    mov dh,24       ;Set the row to start printing at
    mov dl,68       ;Set the column to start printing at

GetFunctionAndSub:
    mov ah,13h      ;BIOS Function 10h - String Output
    mov al,0        ;BIOS Sub-Function (0-3)

Execute:
    int 10h         ;BIOS Interrupt 10h

EndProg:
    mov ax,4c00h    ;Terminate program return 0 to OS
    int 21h         ;DOS Interrupt 21h

end Main
end

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


.model small
.stack
.data
    ;Constants
    ScreenSeg   equ     0B800h

    ;Variables
    MyMsg   db  'Hello World'
    StrLen  equ $-MyMsg

.code
Main:               

SetSeg:
    mov ax, ScreenSeg   ;set segment register:
    mov ds, ax

InitializeStringLoop:   ;Display all characters: - Not working :( Y!
    mov cx, StrLen      ;number of characters.
    mov di, 00h         ;start from byte 'h'

OutputString:
    mov [di], offset byte ptr MyMsg[di]
    add di, 2           ;skip over next attribute code in vga memory.
    loop OutputString

InitializeAttributeLoop:;Color all characters: - Atributes are working fine.
    mov cx, StrLen      ;number of characters.
    mov di, 01h         ;start from byte after 'h'

;Assuming I have all chars with same attributes - fine for now - later I would make this
;into a procedure that I will just pass the details into. - But for now I just want a
;basic output tutorial.

OutputAttributes:
    mov [di], 11101100b     ;light red(1100) on yellow(1110)
    add di, 2               ;skip over next ascii code in vga memory.
    loop OutputAttributes

EndPrg:
    mov ax, 4C00h
    int 21h
end Main

Конечно, я хочу сократить количество используемых инструкций до самого необходимого. (для надлежащего обучения, меньше покрывать при обучении других). По этой причине я не использовал MOVSB ​​/ W / D ect с REP. Вместо этого я выбрал простой для объяснения ручной цикл с использованием стандартных MOV, INC, ADD и т. Д. Это достаточно простые инструкции, которые легко объяснить новичкам. Так что, если возможно, я хотел бы сохранить его как можно ближе к этому.

Я знаю, что все, что кажется неправильным, - это цикл для фактического обработчика строк. Это не позволяет мне увеличивать адрес так, как я хочу. Меня это смущает, потому что я на самом деле неплохой программист, использующий C ++, C #, VB и Delphi (когда-то давно)). Я знаю, вы бы не подумали, что, учитывая, что я даже не могу получить цикл прямо на ассемблере, но это совсем другой язык. В языках высокого уровня есть 2 или 3 цикла, и кажется, что существует бесконечная комбинация способов создания циклов в ассемблере в зависимости от инструкций. Итак, я говорю «Простая петля», но на самом деле в этом нет ничего простого.

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


person Francis Rodgers    schedule 28.07.2011    source источник


Ответы (3)


Типичным соглашением было бы использовать ds:si в качестве источника и es:di в качестве пункта назначения.

Таким образом, это будет похоже на (непроверено):

  mov ax, @data
  mov ds, ax
  mov ax, ScreenSeg
  mov es, ax
  ...
  mov si, offset MyMsg
OutputString:
  mov al, byte ptr ds:[si]
  mov byte ptr es:[di], al
  add si, 1           ; next character from string
  add di, 2           ; skip over next attribute code in vga memory.
  loop OutputString
person ninjalj    schedule 28.07.2011
comment
Я попытался включить ваш код, но пока у меня проблема с этой строкой: mov es: [di], byte ptr ds: [si] - Я думаю, это связано с синтаксисом MASM 6.14 сообщает мне Invalid Instruction Operands. EMU8086 сообщает мне неправильные параметры. Я обычно не использую EMU8086, потому что он немного отличается по синтаксису от истинного MASM 6.14, но он отлично подходит для быстрого обнаружения ошибок и пошагового выполнения программы построчно. Вы указали мне правильное направление, и я, возможно, смогу это понять. Спасибо за вашу помощь. - person Francis Rodgers; 29.07.2011
comment
Вы должны сделать это двумя инструкциями - загрузить байт в регистр, а затем снова сохранить его в памяти. - person Bo Persson; 30.07.2011
comment
@Bo Persson, Всем спасибо. Это было большим подспорьем. Я разработал свой ответ, поэтому, если кто-то захочет увидеть окончательный код, просто ответьте на этот комментарий, и я опубликую его, когда я полностью закончу. Вы все мне очень помогли. - person Francis Rodgers; 30.07.2011
comment
Альтернатива: movsb / inc di. С cld (флаг направления = 0) вне цикла. Одной из причин использования соглашений es: di и ds: si являются строковые инструкции, такие как movsb. (Несмотря на название, с rep для повторения CX раз они больше похожи на memcpy, чем на strcpy: строки с явной длиной.) - person Peter Cordes; 30.04.2020

Я бы посоветовал получить пакет Masm32, если у вас его еще нет. Он в основном ориентирован на легкое использование языка ассемблера в «Windows сегодня», что очень приятно, но также многому вас научит об Asm, а также покажет, где взять руководства по чипам Intel, упомянутые в предыдущем ответе, которые необходимы.

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

Я играю именно с тем, о чем вы говорите, с Direct Hardware, и я также узнал, что Windows изменила некоторые службы DOS, и службы BIOS также изменились, так что некоторые больше не работают. На самом деле я пишу небольшую программу .com и запускаю ее из Win7 в окне командной строки, печатает сообщение и ждет ключа. Довольно круто, учитывая, что это Win7 в 2012 году!

На самом деле это был BIOS 10h - 0Eh, который не работал, поэтому я попробовал Dos 21h 02h для записи на экран, и он сработал. Код ниже, потому что это .com (командная программа), я подумал, что он может быть вам полезен.

; Это делает программу .com (64k Limit, Code, Data и все остальное; должно умещаться в этом пространстве. Используется для небольших утилит и; подходит для очень быстрых задач. На самом деле команды DOS в основном; небольшие программы .com, подобные этой (кроме полезнее)!;; Выполните сборку с помощью Masm, используя; c: \ masm32 \ bin \ ml / AT / c bfc.asm; Соединитесь с Link16 Masm, используя; c: \ masm32 \ bin \ link16 bfc.obj, bfc.com;; ; Link16 - это ключ к созданию этого 16-битного файла .com (Command)

SEGMT SEGMENT
org 100h

Start:
        push    CS
        pop     DS

        MOV SI, OFFSET Message
Next:
        MOV ah, 02h             ; Write Char to Standard out
        MOV dl, [si]            ; Char
        INT 21h                 ; Write it
        INC si                  ; Next Char
        CMP byte ptr[si], 0     ; Done?
        JNE Next                ; Nope

WaitKey:
        XOR ah, ah              ; 0
        INT 16h                 ; Wait for any Key
ExitHere:        
        MOV ah, 4Ch             ; Exit with Return Code
        xor al, al              ; Return Code
        INT 21h

Message db  "It Works in Windows 7!", 0

SEGMT ENDS
END Start
person BillHudson    schedule 04.02.2012

Раньше я делал все, о чем вы говорите. Пытаюсь вспомнить детали. Майкл Абраш - это имя, которое вам следует искать в Google. Mode-X, например, режим 200 с чем-то на 200 (240x200?) 256 цветов был очень популярен, поскольку он нарушал 16-цветную границу, и в то время игры выглядели действительно хорошо.

Я думаю, что программирование на металлическом регистре было выполнимым, но болезненным, и вам, вероятно, потребуется получить справочник программистов / таблицу данных для интересующего вас чипа. Со временем от CGA к EGA, от VGA к VESA изменился и способ работы. . Я думаю, что обычно вы используете вызовы int something, чтобы получить доступ к фрейму страницы, тогда вы могли бы заполнить это напрямую. VESA, я думаю, сработал именно так, VESA спасла жизнь, когда дело дошло до поддержки видеокарт, раньше вам приходилось писать свои собственные драйверы для каждого чипа (если вам не нужны уродливые стандартные режимы).

Я бы посмотрел на mode-x или vesa и пошел бы оттуда. В любом случае вам нужно иметь немного хакера, чтобы пройти через это, очень редко можно найти полное и точное техническое описание / справочное руководство для программистов, вам всегда нужно просто протолкнуть несколько байтов, чтобы увидеть, что происходит. Начните заполнять те блоки памяти, которые должны быть рамками страниц, пока не увидите, что на экране что-то изменилось ...

Я не вижу в своей библиотеке каких-либо конкретных книг по программированию графики, кроме абраш-книг, таких как черная книга по графическому программированию, которая была в конце этого периода времени. У меня есть ссылки на программистов bios и dos, а также я использовал список ralf Browns. Я уверен, что у меня были копии руководств по популярным видеочипам (до того, как Интернет вспомнил, что вы звонили человеку по этому телефону, на котором висел шнур, человек брал печатное руководство, иногда красиво переплетенное, иногда просто скрепку в угол, если это, положите его в конверт и отправьте вам по почте, и это была ваша единственная копия, если вы не пропустили ее через копировальный аппарат). У меня есть стопки печатных материалов, которые, к сожалению, не собираюсь использовать, чтобы ответить на этот вопрос. Я буду держать этот вопрос в уме и поискать дополнительную информацию, на самом деле у меня могут быть под рукой некоторые из моих старых программ, отрисовывающих фракталы и другие подобные вещи (непосредственно на видеокарте / памяти).

РЕДАКТИРОВАТЬ.

Я знаю, что вы ищете материал для текстового режима, и это графический режим, но он может пролить или не пролить свет на то, что вы пытаетесь сделать. комбинация вызовов int и заполнения страниц и памяти палитры напрямую.

http://dwelch.s3.amazonaws.com/fly.tar.gz

person old_timer    schedule 29.07.2011
comment
Я вижу замешательство. вызовы палитры и режима BIOS очень расплывчаты относительно того, как размещена память 0xB800 (кроме того, что 0xB800 - это адрес, который вы используете). - person old_timer; 29.07.2011
comment
Очень хорошая книга, если вы можете найти ее ISBN 0-201-51806-6 Системный BIOS для компьютеров IBM PC / XT / AT и совместимых устройств из серии технических справочников Pheonix. имеет, например, списки регистров и адреса для регистров mda, cga, ega, vga. список вызовов bios, как ralf-brown, какие регистры что делают и т. д. не содержит информации, которая вам нужна напрямую, требуется взлом, чтобы выяснить, как отображается память, когда вы используете вызов bios для переключения в фоновой или фоновой палитре страницы и т. д. - person old_timer; 29.07.2011
comment
на самом деле у меня есть и первое, и второе издание этой книги. Похоже, вы можете найти их в продаже подержанными. Я долгое время не смотрел на список ralf Browns, возможно, большая часть этого уже там. - person old_timer; 29.07.2011
comment
Я смутно помню тот телефон с торчащим шнуром !! Это возвращает воспоминания! Кроме того, в качестве вспомогательного средства, чтобы вы не тратили слишком много времени на поиски, я просто хочу написать несколько руководств по языку ассемблера, но хочу использовать стандартный подход к программированию. Выведите что-нибудь на экран, присвойте значения переменным, затем выведите их, затем перейдите к вводу, затем циклам и решениям и, наконец, методам. Я верю, что люди, изучающие ассемблер, будут иметь за собой достаточную теорию, которую они могут пропустить через первые 4 или 6 глав в большинстве книг. Но пока я даже не могу получить результат ... - person Francis Rodgers; 29.07.2011
comment
У меня есть вывод о функциях dos и функциях BIOS в текстовом режиме. Я вообще не хочу приближаться к графическому режиму, предпочитаю сразу переходить, чтобы выиграть сборку, как только основы будут раскрыты. Если вы собираетесь заниматься графикой, можно также использовать современные инструменты, поскольку с тех пор сборка сильно изменилась. В качестве помощи проблема, с которой я столкнулся, заключается в том, что я прочитал следующие книги: Введение в программу сборки для семейства 8086, Prog для ПК на базе 80x86, язык сборки для базовых компиляций Intel, революционное руководство по программе сборки lan, графику прога черная книга и многие другие как уже упоминалось но .... - person Francis Rodgers; 29.07.2011
comment
Все они делают одно и то же, 5 глав вводной теории по аппаратному обеспечению и сборке. 10 глав по разным видам программирования через dos и bios. И несколько советов о том, как делать что-то непосредственно с оборудованием, а затем они это замалчивают. Это безумие. Как будто они намеренно пытаются сделать сборку сложной. Я хочу знать 3 способа сделать все (dos, bios и оборудование), поэтому, когда я пишу учебные пособия, я могу показывать сравнения. Но я хочу, чтобы они были ясными и содержательными. Я считаю ассемблер одним из лучших языков в мире. Печально, что он потерял популярность. Я хочу вернуть его. - person Francis Rodgers; 29.07.2011
comment
Наконец, я знаю, что это может показаться безумием, но я думаю, что если язык ассемблера станет доступным для всех, то мы сможем просто приблизиться к мечте о реальном ИИ. В конце концов, ассемблер - единственный существующий язык, который может записывать в памяти впереди себя, что позволяет ему изменять, писать и переписывать свой собственный код. Мобильные устройства просто слишком слабы, чтобы обрабатывать какие-либо достойные приложения, не только ИИ, что возвращает нас к единственному подходящему языку - ассемблеру. Также любой другой язык ограничивает вас правилами изобретателей языка, сборка неограничена. Спасибо за вашу помощь до сих пор - person Francis Rodgers; 29.07.2011
comment
не беспокойтесь, я просмотрел несколько из моих многочисленных стопок резервных компакт-дисков и не нашел старые резервные копии дней dos / win3x и сдался. Подумал, что у вас будут еще вопросы или комментарии, или кто-то еще что-нибудь найдет. - person old_timer; 29.07.2011
comment
Рад видеть поддержку pro asm. x86 - это не то, что я бы назвал хорошей архитектурой для начала, но у нее есть преимущество в виде процессора (скорее всего), который использует мой компьютер. Я также работаю (медленно) над чем-то с той же целью, но с другим подходом. Так держать, количество и качество людей с низким уровнем знаний ухудшаются. Для этой конкретной задачи вы можете просто попросить их отправить char в стиль tty экрана, стиль uart во встроенной системе, достаточно отладочного пути, чтобы изучить asm без необходимости слишком углубляться в сам дисплей. - person old_timer; 29.07.2011
comment
Посмотрите на thumbulator на github или мой симулятор набора инструкций msp, чтобы понять, что я имею в виду, простой способ написать некоторый текстовый стиль uart из порта, чтобы вы могли видеть, что происходит, без того, чтобы этот порт отладки был большой частью проекта . Пусть изучение инструкций asm станет большой частью проекта. - person old_timer; 29.07.2011