MS-DOS и TASM 2.0. Часть 16. Прерывания DOS.
Ядро операционной системы — набор системных функций.
Основу операционной системы Windows 95 — Windows XP составляет набор системных функций, содержащихся в файлах с расширением *.DLL, которые располагаются в системных дирректориях … Windows\System, System32, SysWOW64 (для 64 битных версий операционок) — так называемый Win API. К слову, в Windows 10 поддержка Win API реализована практически в полном объёме, хотя ядро системы несколько изменилось). В MS-DOS ядро также состоит из системных функций, которые называются прерывания DOS. Ну, если точно, то есть прерывания DOS, а есть прерывания BIOS (связаны с управлением компьютерным железом, определённые прерывания DOS можно реализовать через прерывания BIOS), да и понятие ядра системы можно расширить… Для наших целей и на данный момент отбросим усложнения в сторону! Далее мы будем использовать общее понятие для всех прерываний: прерывания DOS.
Прерывания DOS.
Прерывание имеет вид: int [номер прерывания], например: INT 21h.
Функции прерывания INT 21h делят на группы в зависимости от выполняемых ими задач и особенностей выполнения этих задач. Одно и тоже действие иногда можно осуществить при помощи различных прерываний различными способами.
Прерывание не имеет смыслового названия, но каждой функции присвоен свой номер. Номер функции при вызове прерывания INT 21h задается через регистр AH. Согласно этому номеру можно выяснить предназначение функции, её параметры.
Параметры (in, out) передаются через регистры либо пары регистров (например: BX, DX, CX, BL:CX, DS:DX, и т.д.). Возвращаемое значение (return) передаётся через AX.
0dh 0ah ассемблер что это
Как и в случае вывода на экран, DOS предоставляет набор функций для чтения данных с клавиатуры, которые используют стандартное устройство ввода STDIN, так что можно использовать в качестве источника данных файл или стандартный вывод другой программы.
Функция DOS 0Ah — Считать строку символов из STDIN в буфер
| Ввод: | АН = 0Ah DS:DX = адрес буфера |
| Вывод: | Буфер содержит введенную строку |
Для вызова этой функции надо подготовить буфер, первый байт которого содержит максимальное число символов для ввода (1 – 254), а содержимое, если оно задано, может использоваться как подсказка для ввода. При наборе строки обрабатываются клавиши Esc, F3, F5, BS, Ctrl-C/Ctrl-Break и т.д., как при наборе команд DOS (то есть Esc начинает ввод сначала, F3 восстанавливает подсказку для ввода, F5 запоминает текущую строку как подсказку, Backspace стирает предыдущий символ). После нажатия клавиши Enter строка (включая последний символ CR (0Dh)) записывается в буфер, начиная с третьего байта. Во второй байт записывается длина реально введенной строки без учета последнего CR.
Рассмотрим пример программы, выполняющей преобразование десятичного числа в шестнадцатеричное.
Функция 0Ah предоставляет удобный, но ограниченный способ ввода данных. Чаще всего используют функции посимвольного ввода, позволяющие контролировать отображение символов на экране, реакцию программы на функциональные и управляющие клавиши и т.д.
Функция DOS 01h — Считать символ из STDIN с эхом, ожиданием и проверкой на Ctrl-Break
| Ввод: | АН = 01h |
| Вывод: | AL = ASCII-код символа или 0. Если AL = 0, второй вызов этой функции возвратит в AL расширенный ASCII-код символа |
При чтении с помощью этой функции введенный символ автоматически немедленно отображается на экране (посылается в устройство STDOUT — так что его можно перенаправить в файл). При нажатии Ctrl-C или Ctrl-Break выполняется команда INT 23h. Если нажата клавиша, не соответствующая какому-нибудь символу (стрелки, функциональные клавиши Ins, Del и т.д.), то в AL возвращается 0 и функцию надо вызвать еще один раз, чтобы получить расширенный ASCII-код (см. приложение 1).
В трех следующих вариантах этой функции код символа возвращается в AL по такому же принципу.
Функция DOS 08h — Считать символ из STDIN без эха, с ожиданием и проверкой на Ctrl-Break
| Ввод: | АН = 08h |
| Вывод: | AL = код символа |
Функция DOS 07h — Считать символ из STDIN без эха, с ожиданием и без проверки на Ctrl-Break
| Ввод: | АН = 07h |
| Вывод: | AL = код символа |
Функция DOS 06h — Считать символ из STDIN без эха, без ожидания и без проверки на Ctrl-Break
| Ввод: | АН = 07h DL = 0FFh |
| Вывод: | ZF = 1, если не была нажата клавиша, и AL = 00 ZF = 0, если клавиша была нажата. В этом случае AL = код символа |
Кроме перечисленных функций могут потребоваться и некоторые служебные функции DOS для работы с клавиатурой.
Функция DOS 0Bh — Проверить состояние клавиатуры
| Ввод: | АН = 0Bh |
| Вывод: | AL = 0, если не была нажата клавиша AL = 0FFh, если была нажата клавиша |
Эту функцию удобно использовать перед функциями 01, 07 и 08, чтобы не ждать нажатия клавиши. Кроме того, вызов этой функции позволяет проверить, не считывая символ с клавиатуры, была ли нажата комбинация клавиш Ctrl-Break; если это произошло, выполнится прерывание 23h.
Функция DOS 0Ch — Очистить буфер и считать символ
| Ввод: | АН = 0Ch AL = Номер функции DOS (01, 06, 07, 08, 0Ah) |
| Вывод: | Зависит от вызванной функции |
Функция 0Ch очищает буфер клавиатуры, так что следующая функция чтения символа будет ждать ввода с клавиатуры, а не использовать нажатый ранее и еще не обработанный символ. Например, именно эта функция используется для считывания ответа на вопрос «Уверен ли пользователь в том, что он хочет отформатировать диск?».
Функции посимвольного ввода без эха можно использовать для интерактивного управления программой, как в следующем примере.
В этом примере для вывода на экран используется прямое копирование в видеопамять, так как вызов функции BIOS вывода строки (INT 10h, АН = 13h) прокручивает экран вверх на одну строку при выводе символа в нижнем правом углу экрана.
MS-DOS и TASM 2.0. Часть 10. Команды ассемблера.
Команды ассемблера и команды процессора.
Стоит пояснить, что если к вопросу подойти формально строго, то команды процессора и команды ассемблера — это не одно и то же. Ассеммблер — хоть и низкоуровневый язык программирования, но иногда он без спроса программиста «корректирует код под себя». Причём у каждого ассемблера (masm, tasm, fasm) это может быть по-разному. Самый яркий пример — команда ret. В ассемблерном коде мы запишем ret, а реальный ассемблер ассемблирует её как retf или retn 8. Может также изменяться код, добавлением в качестве выравнивания кода команды процессора nop (об этом ниже в статье) и т.п. Чтобы не усложнять суть вопроса, под понятиями команды процессора и команды ассемблера мы будем подразумевать одно и то же.
Команды процессора (команды ассемблера) в большинстве своём работают с аргументами, которые в ассемблере называются операндами. Система машинного кода процессоров Intel содержит более 300 команд (команды процессора, сопроцессора, MMX-расширения, XMM-расширения). С каждым новым процессором их количество растёт. Для того, чтобы профессионально программировать, не надо зубрить и разбирать все команды процессора. При необходимости можно воспользоваться справочником. В процессе чтения статей, вы поймёте, что основная суть знания ассемблера состоит не в доскональном знании всех команд, а в понимании работы системы.
Не следует забывать, что команды процессор видит в виде цифр, которые можно рассматривать как данные. Например, команда NOP занимает один байт и её машинный код — 90h.
Начиная изучать язык низкого уровня, мы будем иметь дело с ограниченным набором старых-добрых команд процессора. Иные команды ассемблера понадобятся специалистам, заинтересованным в оптимизацией кода, связанного со сложными математическими расчетами данных большого объёма.
Основные (т.н. целочисленные) команды ассемблера позволяют написать практически любую программу для операционных систем MS-DOS и Windows. Количество команд ассемблера, которыми вы будете пользоваться будет расти со временем прохождения курса. Для более детального понимания, в последствии можете обратиться к справочнику команд.
Рассмотрим команды ассемблера на практическом примере.
С использованием среды разработки TASMED или любого текстового редактора набираем код. Программа, задаст вопрос на английском языке о половой принадлежности (имеется ввиду ваш биологический пол при рождении). Если вы нажмете m (Man), будет выведено приветствие с мужчиной, если w (Woman), то с женщиной, после этого программа прекратит работу. Если будет нажата любая другая клавиша, то программа предположит, что имеет дело с гоблином, не поверит и будет задавать вам вопросы о половой принадлежности, пока вы не ответите верно.
FasmWorld Программирование на ассемблере FASM для начинающих и не только
Учебный курс. Часть 13. Циклы и команда LOOP
Автор: xrnd | Рубрика: Учебный курс | 19-04-2010 |
Распечатать запись
До этой части все наши программы выполнялись последовательно — в них не было ветвлений и переходов. Сегодня мы научимся делать простейшие циклы. Циклом называется повторяющееся выполнение последовательности команд. Но для начала нужно научиться объявлять метки.
Синтаксис объявления меток
Метка представляет собой символическое имя, вместо которого компилятор подставляет адрес. В программе на ассемблере можно присвоить имя любому адресу в коде или данных. Обычно метки используются для организации переходов, циклов или каких-то манипуляций с данными. По сути имена переменных, объявленных с помощью директив объявления данных, тоже являются метками. Но с ними компилятор дополнительно связывает размер переменной. Метка объявляется очень просто: достаточно в начале строки написать имя и поставить двоеточие. Например:
m1: mov ax,4C00h int 21h
Теперь вместо имени m1 компилятор везде будет подставлять адрес комады mov ax,4C00h. Можно объявлять метку на пустой строке перед командой:
exit_app: mov ax,4C00h int 21h
Имя метки может состоять из латинских букв, цифр и символов подчёркивания, но должно начинаться с буквы. Имя метки должно быть уникальным. В качестве имени метки нельзя использовать директивы и ключевые слова компилятора, названия команд и регистров (в этом случае FASM покажет сообщение об ошибке). FASM различает регистр символов в именах меток. Можно также объявлять несколько меток на один адрес. Например:
no_error: exit_app: m1: mov ax,4C00h
Подробнее о синтаксисе объявления меток рассказывается в части 27.
Команда LOOP
Для организации цикла предназначена команда LOOP. У этой команды один операнд — имя метки, на которую осуществляется переход. В качестве счётчика цикла используется регистр CX. Команда LOOP выполняет декремент CX, а затем проверяет его значение. Если содержимое CX не равно нулю, то осуществляется переход на метку, иначе управление переходит к следующей после LOOP команде.
Пример цикла
В качестве примера я приведу простую программу, которая будет печатать все буквы английского алфавита. ASCII-коды этих символов расположены последовательно, поэтому можно выводить их в цикле. Для вывода символа на экран используется функция DOS 02h (выводимый байт должен находиться в регистре DL).
Вложенные циклы
Иногда требуется организовать вложенный цикл, то есть цикл внутри другого цикла. В этом случае необходимо сохранить значение CX перед началом вложенного цикла и восстановить после его завершения (перед командой LOOP внешнего цикла). Сохранить значение можно в другой регистр, во временную переменную или в стек. Следующая программа выводит все доступные ASCII-символы в виде таблицы 16×16. Значение счётчика внешнего цикла сохраняется в регистре BX.
Как видите, всё довольно просто 🙂 Результат работы программы выглядит вот так:
Упражнение
:только я не совсем понял, надо ли выводить результат на экран
use16
org 100h
mov cx,n
mov bx,3
mov ax,bx
lp:
imul bx,ax
loop lp
mov ax,4c00h
int 21h
Хорошо написано, но не совсем верно. Смотри сам, если n=1, то должно получиться 3, а твоя программа получит 9. На одно умножение больше получается. Кроме того, если a — число без знака, то результат лучше считать командой MUL.
Чтобы вывести число на экран, нужно сначала преобразовать его в текстовую строку (или в отдельные символы), поэтому тут всё не так просто. Но можешь попробовать 🙂 Я хотел этой теме отдельную статью посвятить.
; а если так, то с n=1, должно вроде правильно показывать, но что то у меня
; отладчик много циклов показывает, если я ввожу к примеру n db 2
use16
org 100h
mov cx,n
mov bx,1
mov ax,3
lp:
imul bx,ax
loop lp
mov ax,4c00h
int 21h
Я в первый раз не заметил. Да, циклов будет много 🙂 Потому что команда «mov cx,n» загружает в CX адрес переменной, а не её значение. Не хватает квадратных скобок. И лучше использовать команду movzx, так как размер n — 8 бит, а размер CX — 16 бит.
movzx cx,[n]
mov bx,1
mov ax,3
lp:
imul bx,ax
loop lp
mov ax,4c00h
int 21h
Почти правильно 🙂 Тебе ещё нужно использовать команду MUL вместо IMUL, чтобы было совсем хорошо. 3 10 =59049. Если ты умножаешь командой IMUL, то получится ошибка, потому что результат этой команды — слово со знаком. Предел его значения 32767.
movzx cx,[n]
mov bx,3
mov ax,1
lp:
mul bx
loop lp
mov word[a],ax
mov word[a+2],dx
mov ax,4c00h
int 21h
Да теперь правильно 🙂 Только одна команда лишнаяя: «mov word[a+2],dx». Либо надо объявлять a как двойное слово с помощью dd.
MS-DOS и TASM 2.0. Часть 7. Данные.
Данные в ассемблере.
Данные в ассемблере — понятие широкое. Программу в целом можно воспринимать как одну большую совокупность данных, однако мы уже знаем и помним, что она состоит из данных и кода — набора команд, необходимых для обработки данных.
Данные в ассемблере в узком понимании (буква, строка, символ, текстовый файл, звуковой файл, видеофайл, документ Word и т.п), а также сам код представляют собой определённую строго регламентированную последовательность чисел. Эта последовательность формируется при преобразовании программного текста в исполняемый файл, то есть написанный программистом код транслируется в машинный язык цифр.
Машина манипулирует минимальным блоком памяти размером в 1 байт. Байт состоит из 8 бит и может содержать 256 значений (2 в степени 8). Байтовый мир машин транслируется отладчиками, дизассемблерами и HEX-редакторами в 16-тиричном виде для более удобного восприятия человеком.
Для дальнейшего изучения вопроса нам понадобиться редактор HIEW. Он есть среди прочего необходимого в архиве DOS-1.rar, который необходимо скачать.
Байты, слова, двойные слова …
Фактически все программы — от простых до самых сложным представляют собой набор команд процессора, манипулирующих с данными.
Команды процессора представляют собой цифровые значения, имеющие свою структуру.


Распечатать запись 

