Как вывести строку на экран в Ассемблере

Как вывести строку на экран в Ассемблере

Что бы ни делала ваша программа, в большинстве случаев она должна выводить какие-то данные на экран. И если в языках высокого уровня это делается “лёгким движением руки”, то в ассемблере для этого приходится как следует помучиться.

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

Итак, выводить строки на экран можно двумя путями:

  1. Посимвольно (то есть в цикле выводить каждый символ строки).
  2. Строку целиком.

Кроме того, в текстовом режиме вывод на экран можно выполнить одним из трёх способов:

  1. С помощью функций DOS.
  2. С помощью функций BIOS.
  3. Путём прямой записи в видеопамять.

Третий способ хорош тем, что он сразу записывает данные в видеопамять, что позволяет выполнять вывод более быстро. Однако в наше время он применим, разве что, в учебных целях. Потому что современные операционные системы не позволяют напрямую обращаться к “железу”.

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

Функции вывода DOS

Итак, начнём с функций вывода DOS. Эти функции являются функциями операционной системы DOS, но поддерживаются и операционными системами Windows.

Как я уже говорил, можно напечатать на экране строку в цикле, отдельно выводя каждый символ. Для этих целей можно использовать функции 02h, 06h или недокуметированное прерывание 29h.

Если требуется вывести на экран строку целиком, то можно применить функции 09h и 40h.

Для использования функций DOS надо сначала подготовить необходимые данные, записать номер функции в регистр AH, а затем вызвать прерывание 21h.

Все функции рассматривать здесь не будем. Для примера используем одну из самых простых функций DOS — функцию 09h, которая выводит в стандартное устройство вывода (в нашем случае — на экран) строку, адрес которой находится в DS:DX. Строка должна заканчиваться символом $, иначе функция не поймёт, где конец строки, и программа будет выводить много-много символов из памяти, начиная с указанного адреса. Примерно так, как показано на рисунке:

Неправильное использование функции DOS 09h

При правильном использовании на экран будет выведено примерно следующее:

Правильное использование функции DOS 09h

Функции вывода BIOS

Функции BIOS также могут выводить как отдельные символы (функции 09h, 0Ah, 0Eh), так и строки целиком (функция 13h).

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

Хотя функции DOS тоже могут считывать символы, но всё-таки возможности BIOS более широки.

Для работы с функциями BIOS также сначала надо подготовить данные, записать номер функции в регистр AH, а затем вызвать прерывание 10h.

Для примера рассмотрим функцию 13h. Перед вызовом функции надо:

  • Записать номер функции в регистр АН.
  • Записать режим вывода в регистр AL:
    • бит 0: переместить курсор в конец строки после вывода.
    • бит 1: строка содержит не только символы, но и атрибуты. Так что каждый символ описывается двумя байтами — ASCII-код и атрибут. Это можно использовать, если в строке символы должны иметь, например, разный цвет. Если атрибуты одинаковы для всей строки, то этот бит лучше сбросить (обнулить).
    • биты 2-7: не используются.

    Использование функции BIOS 13h

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

    Источник

    Вывод строки символов с клавиатуры ассемблер

    Способы ввода данных с клавиатуры

    Процесс ввода информации в ассемблерных программах осуществляется аналогично выводу. Ниже описан ряд функций прерывания 21h, использующихся для ввода информации с клавиатуры.

    Функция 01h

    Ввод с клавиатуры.

    Выход: AL= символ, полученный с клавиатуры

    Описание: Считывает (ожидает) символ со стандартного входного устройства. Отображает этот символ на стандартное выходное устройство (эхо). Ввод расширенных клавиш ASCII (F1-F12, PgUp, курсор и т.п.) требует двух обращений к этой функции. Первый вызов возвращает AL=0. Второй вызов возвращает в AL расширенный код ASCII.

    Функция 07h

    Нефильтрующий консольный ввод без эха.

    Выход: AL= символ, полученный с клавиатуры

    Описание: Считывает (ожидает) символ со стандартного входного устройства и возвращает этот символ в AL. Не фильтрует: Не проверяет на Ctrl-Break, backspace и т.п. Необходимо вызывать дважды для ввода расширенного символа ASCII.

    Функция 08h

    Консольный ввод без эха.

    Выход: AL= символ, полученный с клавиатуры

    Описание: Считывает (ожидает) символ со стандартного входного устройства и возвращает этот символ в AL. При обнаружении Ctrl-Break выполняется прерывание INT 23H. Необходимо вызывать дважды для ввода расширенного символа ASCII.

    Функция 0ah

    Буферизированный ввод строки.

    DS:DX=адрес входного буфера (смотри ниже)

    Выход: буфер содержит ввод, заканчивающийся символом CR (ASCII 0dH)

    Описание: При входе буфер по адресу DS:DX должен быть оформлен следующим образом:

    MAX — максимально допустимая длина ввода (от 1 до 254) При выходе буфер заполнен данными следующим образом:

    max len T E X T … 0dh

    LEN — действительная длина данных без завершающего CR (здесь – 0dH). Символы считываются со стандартного ввода вплоть до CR (ASCII 0dH) или до достижения длины MAX-1. Если достигнут MAX-1, включается консольный звонок для каждого очередного символа, пока не будет введен возврат каретки CR (нажатие Enter). Второй байт буфера заполняется действительной длиной введенной строки, не считая завершающего CR. Последний символ в буфере -всегда CR (который не засчитан в байте длины). Символы в буфере (включая LEN) в момент вызова используются как «шаблон». В процессе ввода действительны обычные клавиши редактирования: Esc выдает «\» и начинает с начала, F3 выдает буфер до конца шаблона, F5 выдает «@» и сохраняет текущую строку как шаблон, и т.д. Большинство расширенных кодов ASCII игнорируются. При распознавании Ctrl-Break выполняется прерывание INT 23H (буфер остается неизменным).

    Функция 0ch

    Ввод с очисткой

    AL= номер функции ввода DOS (01H, 06H, 07H, 08H или 0aH)

    Описание: Очищает буфер опережающего ввода стандартного ввода, а затем вызывает функцию ввода, указанную в AL. Это заставляет систему ожидать ввод очередного символа. Следующие значения допустимы в AL: 01H Ввод с клавиатуры; 06H Ввод с консоли; 07H Нефильтрующий без эха; 08H Ввод без эха; 0aH Буферизованный ввод.

    Примеры программ

    Далее программы будут оформляться в виде COM.

    Рассмотрим программу которая осуществляет ввод строки с клавиатуры и заменяет все буквы «а» на заглавные, причем пробелы удаляются.

    ;выводим приглашение

    mov dx,offset message

    ;вводим строку

    mov dx,offset inpstr

    ;выводим то что ввели

    mov dx,offset inpstr+2

    ;начинаем цикл обработки

    ;с индекса 2 в массиве начинается введеная инфа

    ;нулевое смещение для преобразованной строки

    ;по индексу 1 в массиве находится длинна

    mov cl, byte ptr [inpstr+1]

    ;теперь в cx длинна — для цикла

    lop: mov ah,inpstr[si]

    ;сравниваем элемент строки с буквой «а»

    ;пишем в новую строку заглавную A

    ;увеличиваем индекс для новой строки

    ;пробелы пропускаем!

    met: cmp ah,’ ‘

    ;это не «а» и не пробел- поэтому просто переносим буквув новую строку

    Источник

    XI Международная студенческая научная конференция Студенческий научный форум — 2019

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

    Операции ввода/вывода по прерыванию INT 21H

    Уникальность ассемблера состоит в том, что он напрямую указывает процессору режим работы с графикой. В ассемблере существует множество режимов, которые определяются шестнадцатеричным числом, содержащимся в регистре АH. Рассмотрим эти примеры прерываний.

    AH=01: Ввод с клавиатуры с отображением в консоли. Данная операция считывает с консолисимвол и помещает его в регистр AL. После считывания содержимое данного регистра представляет собой ASCII-символ. Если после считывания символа регистр AL будет равен 0, значит, с клавиатуры были нажаты специальные клавиши (F1, PgUp и т.д). Для определения их кода необходимо повторить запрос.

    AH=02: Вывод символа в консоль. При выводе символа на экран в текущую позицию курсора необходимо поместить код данного символа в регистр DL.

    AH=06: Ввод/вывод символов. Данный режим может использоваться, как для ввода, так и для вывода. Для вывода в консоль символа необходимо поместить его в DL и вызвать прерывание INT 21H. Для ввода символа необходимо занести в DL FFh и вызвать прерывание INT 21H. При использовании данной команды программа не остановиться, а продолжит выполняться в штатном режиме. При вводе символ поместиться в регистр AL.

    AH=07:Ввод с клавиатуры без отображения в консоли. Данная команда работает аналогично с командой при AH=01H, но немного отличается. При вводе символа с клавиатуры он не отображается на экране.

    AH=09H: Вывод строки в консоль. Для вывода строки необходимо, чтобы она заканчивалась специальным символом ($). Затем адрес начала строки помещается в регистр DX. Символ доллара в консоли не выводится.

    Пример кода выполнения операции прерывания при AH=09H:

    Str DB “Выводимая строка $”

    Leadx, str; смещение регистра DX до начала строки

    Movah, 9; Помещаем в ah 9 для вывода строки

    Int 21h; Прерывание для вывода строки

    AH=0AH: Ввод значений в буфер.При данном режиме работы данные помещаются в буфер, где определена максимальная длина введенной строки. Если при вводе, строка оказывается меньше в длинны буфера, то окончание ввода строки определяется символом клавиши [ENTER], если больше длины буфера, тогда пользователь предупреждается звуковым сигналом. При переполнении буфера введенная строка не учитывается. Во второй байт буфера возвращается реальная длинна введенной строки в байтах. Адрес буфера заносится в регистр DX. Таким образом, в первом байте находится максимальная длина вводимой строки, так как это поле является однобайтовым, значит максимальная длина будет равна 255 символов (FF- шестнадцатеричное представление). Во втором байте храниться реальное количество символов. В третьем байте хранятся введенные символы.

    Ввод /вывод по прерыванию int 10H

    Для вывода символов в консоль или их ввода используются различные команды DOS. Однако он не поддерживает смену цвета в консоли ни перемещение курсора, но возможности DOS можно увеличить при помощи драйвера ANSI.SYS. С графической составляющей всё гораздо хуже в DOS нет никаких графических команд. Зато можно переключить видеоадаптер в графический режим с помощью Esc-последовательностей. Для осуществления перехода необходимо обратиться к нижним уровням операционной системы, называемой BIOS (BasicIn-OutSystem). Программы Bios находятся в ПЗУ(постоянное запоминающее устройство). BIOS в отличии от DOS (все команды выполняются при помощи инструкций прерываний int 21h), выполнение команд осуществляется при помощи различный команд прерываний, то есть за каждым устройством закреплён определённая команда прерываний (клавиатура- int 16h, экран-int 10h, и так далее). Прерывание int 10h выполняет все команды видеоадаптера: вывод строк и символьной информации, смена шрифтов, смена цвета, работа с изображениями и т.д.

    Пример: Вывод на экран горизонтальной прямой

    ;Устанавливаем графический режим

    mov ah,00h ;(1)Команда для задания режима

    mov al,10h ;(2)Входим в графический режим

    int 10h ;(3)Вызов BIOS

    mov si,150 ;(4)si- Начальная координата (X)

    mov cx,300 ;(5)Количество точек по горизонтали

    pushcx ;(6)Помещаем количество точек в стек

    mov ax,0Ch ;(7)Команда вывода пикселя

    mov al,4 ;(8)Устанавливаем цвет красный

    mov bh,0 ;(9)Видеостраница

    movcx,si ;(10)Х-координата (изменяется)

    mov dx,175 ;(11)Y-координата (постоянная)

    int 10h ;(12)Вызов BIOS

    incsi ;(13)Инкремент Х-координаты

    popcx ;(14)Восстановим количество шагов

    loopliniya ;(15)Цикл из CX шагов

    ;Останавливаем программу для просмотра её работы

    mov ah,08h ;(16)Команда ввода с клавиатуры без отображения в консоли

    int 21h ;(17)Вызов DOS

    ;Переключаем видеоадаптер в текстовый режим

    mov ah,00h ;(18)Команда задания режима

    mov al,03h ;(19)Текстовый режим

    int 10h ;(20)Вызов BIOS

    В 1-3 строчках при помощи команды 00H вызвали прерывание Bios 10h и осуществили переключение видеоадаптера в режим графики. Затем поместили номер режима в регистр AL, всего существует порядка 256 разных режимов (текстовых и графических), однако на сегодняшний день используется порядка ста режимов. Команда прерывания int 10h обеспечивает графическое отображение с разрешением 640х350 пикселей и около 16 цветов.

    Все изображения рисуются по точкам (пиксели) так как в BIOS нет команд для вывода каких либо геометрических фигур и нет команд закрашивающих области. Для вывода цветного пикселя на экран используется команда 0CH и прерывание int 10h. Данная команда необходима для занесения в регистр AL кода цвета, в BH- номера видеостраницы, в CX – координаты точки по оси Х в, в DX –координаты точки впо оси Y, все координаты вводятся в диапазоне от 0 до 639.

    После того как программа завершила построение изображения в программе существует остановка для просмотра результата построения. Останавливаем программу при помощи команды DOS 08h (ввод символа без отображения на экране , что бы не портить графическое изображение),и при нажатии любой клавиши (кроме управляющих) программа возобновляет работу. Затем в конце программы выполняется переход обратно в стандартный текстовый режим. Если не перейти с графического режима в обычный , то он может помешать работу встроенной программы.

    Рассмотрим параметры вызова команд 0Ch прерывания int 10h. Заносим номер видеостраницы, куда выводится данная точка, в регистр BH. А регистр AL заносим код цвета выводимого пикселя. Данный адаптер содержит 16 цветов. Данный набор из 16 цветов задаётся программно и может изменятся в любой момент выполнения программы.

    Подведём итог графической работы BIOS и прерывания int 10h. Для вывода на экран изображений используется графический режим. Через прерывание int 10h устанавливается текстовый или графический режим. Для установки режима AH обнуляется и в AL заносится код режима работы, а затем выполняется прерывание 10H.

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

    Источник

    

    28. Средства ввода-вывода символьной информации

    Int 21hкоманда, с помощью которой программа, написанная на языка Ассемблера запрашивает сервис DOS для выполнения определённых действий типа ввода данных с клавиатуры или их вывод на экран. Программа, запрашивающая сервис DOS, должна подготовить всю необходимую информацию в регистрах и управляющих блоках, указать в регистре AH номер желаемой функции DOS и затем вызвать прерывание INT 21H.

    Номера некоторых функций прерывания INT 21H:
    АН = 01: Ввод с клавиатуры с эхоотображением. Данная функция возвращает значение в регистре AL, Если содержимое AL не равно нулю, то оно представляет собой стандартный ASCII-символ, например букву или цифру.
    АН = 02: Вывод символа. Для ввода символа на экран в текущую позицию курсора необходимо поместить код данного символа в регистр DL.
    АН = 06: Ввод/вывод данных. Может использоваться как для ввода, так и для вывода. Для вывода занесите в DL выводимый символ (но не FFH!) и вызовите прерывание 21Н. Для ввода в DL занесите FFH, выполните прерывание 21Н.
    АН = 09: Вывод строки символов Выводимая строка должна заканчиваться знаком доллара $. Адрес начала строки должен быть помещен в DX. Знак доллара не выводится.
    AH = 0A: Ввод данных в буфер: Определяется максимальная длина вводимого текста. Это необходимо для предупреждения пользователя звуковым сигналом, если набран слишком длинный текст; символы считываются со стандартного ввода вплоть до CR (ASCII 0dH) или до достижения длины MAX-1. если достигнут MAX-1, включается консольный звонок для каждого очередного символа, пока не будет введен возврат каретки CR (нажатие Enter).. Во второй байт буфера команда возвращает действительную длину введенного текста в байтах. Адрес буфера помещается в региcтр DX.

    Источник

    Справочник программиста на персональном компьютере фирмы IBM. Вывод на терминал
    Страница 22. Вывод строки символов на экран

    Процедуры, которые выводят целые строки символов очень полез-
    ны, но они могут накладывать ограничения на содержимое выводимой
    строки. Надо обращать внимание на то, какие управляющие коды
    (табуляция, пробел и т.п.) интерпретируются, а какие нет. До
    появления AT BIOS не имел функции вывода строки, хотя MS DOS
    всегда имела такую фукнцию. Функция BIOS предоставляет больший
    контроль над атрибутами символов. Естественно, что ее использова-
    ние создает проблему совместимости с предыдущими машинами. Напо-
    минаем, что EGA имеет ПЗУ, расширяющее ROM-BIOS и функция вывода
    строки символов является одним из таких расширений. В этом случае
    любой IBM PC и XT имеет возможность использовать эту процедуру.

    Высокий уровень.

    Бейсик выводит строку точно так же, как и отдельные символы.
    Надо просто написать PRINT S$, где S$ может быть любой строкой
    длиной до 255 символов, которую сконструировала программа. Ин-
    терпретируются 10 управляющих кодов, а именно:

    ASCII 7 звонок
    ASCII 9 табуляция
    ASCII 10 перевод строки
    ASCII 11 курсор в первую позицию экрана (Home)
    ASCII 12 перевод формата (стирает экран + Home)
    ASCII 13 возврат каретки
    ASCII 28 курсор вправо
    ASCII 29 курсор влево
    ASCII 30 курсор вверх
    ASCII 31 курсор вниз

    Все остальные коды выводятся на экран как символы.

    Средний уровень.

    Функция 9 прерывания 21H выводит строку. DS:DX должны указы-
    вать на первый символ строки. Строка должна завершаться символом
    $, что означает, что сам символ $ не может входить в строку.
    Строка может быть любой длины. Функция не переводит автоматически
    курсор на начало следующей строки после завершения вывода; чтобы
    это выполнялось надо добавить в конец строки символы 0AH (перевод
    строки) и 0DH (возврат каретки).

    ;—в сегменте данных
    FIRST_STRING DB 'This is the first string',0AH,0DH,'$'
    SECOND_STRING DB 'And this is the second string$'

    ;—вывод строки
    MOV AH,9 ;номер функции вывода строки
    LEA DX,FIRST_STRING ;загружаем адрес первой строки
    INT 21H ;печатаем строку с позиции курсора
    LEA DX,SECOND_STRING ;загружаем адрес второй строки
    INT 21H ;печатаем строку с начала новой строки

    Интрепретируются следующие управляющие коды:

    ASCII 7 звонок
    ASCII 8 возврат на шаг (BackSpace)
    ASCII 9 табуляция
    ASCII 10 перевод строки
    ASCII 13 возврат каретки

    Функция DOS 40H прерывания 21H также полезна при выводе строк
    на экран. Она требует, чтобы Вы знали длину строки, поскольку ей
    не требуется символа-ограничителя; эта функция особенно удобна
    для дампа текстовых файлов на экран. Исходно эта функция была
    предназначена для вывода в файл. Она требует дескриптора, который
    является идентификационным номером для данного файла или уст-
    ройства. Дисплей имеет заранее предназначенный дескриптор #1.
    Надо поместить дескриптор в BX, а число байтов строки в CX. DS:DX
    должны указывать на строку. Функция выводит текст с нормальными
    (белый на черном) атрибутами. Отметим, что не надо предварительно
    "открывать" дисплей, как это Вы делает с другими файлами при
    использовании этой функции. Вот пример:

    ;—вывод 1000 байтов текста
    MOV AH,40H ;номер функции
    MOV BX,1 ;дескриптор дисплея
    LEA DX,STRING ;загржаем адрес строки
    MOV CX,1000 ;число выводимых байтов
    INT 21H ;

    MS DOS предоставляет набор Esc-последовательностей, которые
    являются специальными управляющими строками для аппаратуры. Когда
    они выводятся с помощью функции 9 прерывания 21H, то они могут
    управлять курсором, режимом дисплея, цветом символов и некоторыми
    аспектами клавиатуры. В приложении Д обсуждается как их использо-
    вать. Когда программа выводит на экран много строк, то Esc-после-
    довательности часто являются самым удобным способом позициониро-
    вания курсора и установки цвета строки. Это происходит потому,
    что они сами рассматриваются просто как очередные строки в серии
    выводимых строк.
    У AT и машин, снабженных EGA, функция 13H прерывания 10H выво-
    дит строку. ES:BP должны указывать на строку, а длина строки
    должна быть в CX. DX указывает позицию курсора, с которой должна
    начинаться строка (вычисляемую как смещение от начала страницы,
    на которую идет вывод без учета байтов атрибутов). В BX должен
    быть указан номер страницы. Наконец номер кода от 0 до 3, содер-
    жащийся в AL указывает как должна выводиться строка.

    AL = 0 строка состоит только из символов, курсор неподвижен
    AL = 1 строка состоит только из символов, курсор движется
    AL = 2 в строке чередуются символы и атрибуты,
    курсор неподвижен
    AL = 3 в строке чередуются символы и атрибуты
    курсор движется

    Когда AL равно 0 или 1, то атрибуты должны находиться в BL. Все
    символы будут выводиться с этими атрибутами. Эта функция интерп-
    ретирует возврат на шаг, перевод строки, возврат каретки и звонок
    как управляющие команды, а не как печатаемые символы.

    Низкий уровень.

    Ограничение на использование символа $ делает функцию 9 беспо-
    лезной для многих приложений. Однако на многих машинах это е-
    динственное прерывание, доступное для вывода строки неизвестной
    длины. Попробуйте написать свое собственное прерывание (в [1.2.3]
    показано как), использующее технику отображения в память [4.3.1].
    Используйте в качестве ограничителя какой-нибудь специальный
    символ, например, ASCII 0, вместо $. Сделайте чтобы эта процедура
    обрабатывала только те управляющие коды, которые нужны Вам. Такой
    метод будет работать намного быстрее, чем при использовании функ-
    ции MS DOS.

    Источник

    Читайте также:  Как управлять клавиатурой с помощью геймпада