Фильтрация шестнадцатеричных чисел

From AsIsWiki
Jump to: navigation, search
Форум

Назад | Оглавление


Contents

Введение

В предыдущей теме была рассмотрена программа для ввода шестнадцатеричных чисел. Но эта программа обладала существенным недостатком: кроме чисел 0 ... F она воспринимала практически все вводимые символы, и интерпретировала их как числа.

Поэтому, нам следует написать процедуру, которая при вводе будет фильтровать символы шестнадцатеричных чисел:

"0" ... "9", "A" ... "F"


Фильтр

Рассмотрим две новые инструкции, которые потребуются для фильтрации чисел:

JA (Jump if Above) - перейти если больше
JB (Jump if Below) - перейти если меньше

Инструкции JA и JB работают только с положительными числами 0 ... FFFFh, и игнорируют флаг переполнения (OF). Изученная ранее инструкция JL (перейти, если меньше), работает как с положительными, так и отрицательными числами (проверяет OF).

Если для запроса символа использовать функцию 01h прерывания INT 21h, то ввод любого символа будет сопровождаться эхом (т.е. выводом данного символа на экран).

Новая процедура не должна отображать ошибочно введенные символы. Для ввода символа без эхо-повтора, мы используем функцию 08h прерывания INT 21h.

Ниже приводится программа-тест для проверки фильтра. Для повышения читабельности, из листинга удалены коды инструкций и сегмент адреса. Инструкции основной программы внесите по адресам 100h и 103h, а процедуру расположите по адресу 200h:

0100 CALL 0200     основная программа
0103 INT  20
0200 PUSH DX       процедура ввода и фильтрации чисел 0 ... F
0201 MOV  AH,08    ввод символа без эха
0203 INT  21
0205 CMP  AL,30
0207 JB   0203     если AL < 30h, то переход на 203h
0209 CMP  AL,46
020B JA   0203     если AL > 46h, то переход на 203h
020D CMP  AL,3A
020F JB   0215     если AL < 3Ah, то переход на 215h
0211 CMP  AL,41
0213 JB   0203     если AL < 41h, то переход на 203h
0215 MOV  AH,02
0217 MOV  DL,AL    печать отфильтрованного символа
0219 INT  21
021B SUB  AL,30
021D CMP  AL,09    преобразование кода символа в число
021F JLE  0223
0221 SUB  AL,07
0223 POP  DX
0224 RET

Протестируйте программу с различными символами и убедитесь, что фильтр пропускает только символы шестнадцатеричных чисел: "0" ... "F". Проверьте ввод символов "a" ... "f".

Почему процедура начинается с адреса 200h? Процедуры могут располагаться в любом месте программы, но обычно их пишут после основной программы. Адрес 200h выбран с учетом места под текст основной программы (100h - ячеек). Можно перенести процедуру на адрес 105h, тогда между основной программой и процедурой не останется свободных ячеек. При этом придется поменять все адреса в инструкциях условных переходов.

В процедуре используются регистры AX и DX, но в стеке сохраняется только регистр DX. Почему? В ходе выполнения процедуры, в AL передается цифра введенная с клавиатуры. Если в начале процедуры сохранить значение регистра AX в стек, а в конце процедуры его восстановить, то введенная внутри процедуры цифра будет потеряна. Поэтому, не каждый регистр можно временно сохранять в стеке.

Данную процедуру можно использовать для ввода двузначных чисел. Например, программа должна запрашивать hex-код символа, и выводить этот символ на экран:

0100 CALL 0200     переход на процедуру ввода hex-цифры
0103 MOV  DL,AL
0105 MOV  CL,04
0107 SHL  DL,CL
0109 CALL 0200     переход на процедуру ввода hex-цифры
010C ADD  DL,AL
010E MOV  AH,02
0110 INT  21
0112 INT  20

Проверьте работу программы с кодами:

  • 2Ah (символ "*")
  • 07h (звуковой сигнал)
  • 40h (символ "@") и др.


Калькулятор

Программа запрашивает две hex-цифры, суммирует их и выводит результат на экран,
например: F + 1 = 10

0100 CALL 0200
0103 MOV  BL,AL
0105 MOV  AH,02
0107 MOV  DL,2B    печать знака "+"
0109 INT  21
010B CALL 0200
0110 MOV  AH,02
0112 MOV  DL,3D    печать знака "="
0114 INT  21
010E ADD  BL,AL
0116 CALL 0150
0119 INT  20
...
0150 Процедура печати двузначного числа из регистра BL
...
0200 Процедура ввода hex-цифры в регистр AL

Программу печати двузначного числа из регистра BL нужно переделать в процедуру:

  1. замените INT 20h на RET;
  2. измените адреса в инструкциях JL;
  3. можете добавить инструкции PUSH и POP (но в данном случае это не обязательно).

Задачи:

  1. Если результат сложения меньше 10h, то в старшем разряде ответа печатается ноль. Например: 3 + 2 = 05. Вам нужно убрать этот "лишний" ноль.
  2. Убрать пустые адресные пространства между основной программой и процедурами. Записать программу на диск.


Усовершенствованный калькулятор

Вы написали программу, которая умеет складывать два шестнадцатеричных числа. Теперь необходимо "обучить" калькулятор вычитанию.

В приложениях находится текст готовой программы. Но не спешите искать готовое решение. Эта программа является итоговой задачей, желательно написать ее самостоятельно. Если вы успешно справитесь с ней, то знайте: время, проведенное за клавиатурой, потрачено не зря.

Ввод-фильтр первой цифры,
копия числа в регистре BH
Ввод-фильтр знака "+" или "-",
копия знака в регистре DH
Ввод-фильтр второй цифры,
копия числа в регистре BL
Ввод-фильтр знака "=".
После ввода "=" появляется ответ
Вычисление результата:
если DH = "+", то BH + BL
если DH = "-", то BH - BL
Вывод результата на экран.
INT 20h
Процедура:
"Вывод символа на экран"
Процедура:
"Ввод-фильтр hex-цифры"

Для написания программы можно использовать приведенную блок-схему, или разработать свой алгоритм.

Решение можно упростить, исключив контроль отрицательных чисел и проверку разрядности числа:

1 - 2 = FF
2 + 3 = 05

В более сложном варианте результат выглядит иначе:

1 - 2 = -1
2 + 3 = 5

Именно так работает программа из приложения.


В работе вам может потребоваться инструкция безусловного перехода JMP (Jump):

JMP 210   переход на адрес 210h


Резюме

Эта статья завершает вводную часть курса "Основы программирования на ассемблере". Теперь вы знаете, что:

  • числа можно представлять не только в десятичной системе счисления;
  • арифметические операции выполняются в любой системе счисления;
  • регистры позволяют хранить в микропроцессоре одновременно несколько чисел;
  • система команд CPU позволяет выполнять арифметические и другие действия;
  • процедуры и прерывания значительно упрощают разработку программ.

Многое из того, что вы написали, будет использовано далее.
Во второй части курса мы перейдем к более серьезным и интересным вопросам программирования на ассемблере.



Форум

Назад | Оглавление

Personal tools
Namespaces

Variants
Actions
Navigation
Tools