- •МІнІстерство оСвІти і науКи УкраЇни
- •Двоичные числа
- •Шестнадцатеричные числа
- •1.2.4. Числа со знаком.
- •Знаковый бит
- •Дополнение до двух.
- •1.2. Представление данных.
- •00001001 (Инверсия бит)
- •Максимальные и минимальные значения
- •Лабораторная работа №2
- •Трансляция программы
- •Компоновка программы
- •Отладка программы
- •Лабораторная работа №3
- •Теоретическая часть Упрощенные директивы сегментации
- •I этап.
- •Лабораторная работа №4
- •Лабораторная работа №5
- •Лабораторная работа №7
- •Вариант №1. (*)
Лабораторная работа №5
Цель работы: изучить правила работы с командами передачи управления.
Вычислить заданное условное выражение для данных в форматах «беззнаковое» целое и «знаковое» целое, используя команды сравнения, условного и безусловного переходов. Результат Y – тоже целочисленный и его диапазон (формат) зависит от специфики решаемого условного выражения. Исходные данные (а,b) – 16-битные. Необходимо осуществить проверку корректности ввода и результата.
Вариант №1. (*)
Написать процедуру, которая размещает два 16-битных числа со знаком в памяти в порядке возрастания (меньшее число заносится в ячейку с меньшим адресом).
Результат: Смещение адреса первого числа берется из регистра ВХ; смещение адреса второго числа - из регистра DI
Вариант №2.
Дано: (0 <= a < 1000, 0 <= b < 1000)
Написать процедуру, которая осуществляет выбор:
Если а < b, то с=a + b;
если a = b, то c=a;
если a > b, то c=a - b
Вариант №3.
Дано: (10 <= x < 240)
Написать процедуру, которая осуществляет выбор:
;Если x < 10, то c=x + 10
;если x = 10, то c=x/10 (частное)
;если x > 10, то c=x - 10
Вариант №4. (*)
Поиск ненулевой ячейки в блоке памяти.
Составить программу, которая находит первый ненулевой элемент в заданном блоке памяти из пяти байтовых элементов. Смещение начального адреса блока берется из регистра ВХ; смещение конечного адреса блока берется из регистра DI.
Смещение адреса ненулевого байта возвращается в регистре ВХ. Если ненулевой байт ненайден, то по возвращении в регистре ВХ будет содержаться то же значение, что и в DI
Указание: использовать команду JNZ.
Вариант №5. (*)
Инвертирование строки.
Написать программу, которая производит замену в строке символов длиной n байт строчных букв латинского алфавита на прописные.
Указание: Строчным буквам в таблице ASCII соответствует диапазон кодов 61h-7ah, а прописным – 41h-5ah. Для составления оптимального алгоритма необходимо сравнить представление соответствующих прописных и строчных букв в двоичном виде:
a – 0110 0001……z – 0111 1010
A – 0100 0001…..Z – 0101 1010
Вариант №6.(*)
Составить программу, которая производит подсчет количества нулевых элементов в области blok длиной n байт.
Указание: использовать команды LOOP, JCXZ, CMP, JNE.
На выходе в AL – количество нулевых элементов.
Вариант №7.
Составить процедуру, которая производит деление двух беззнаковых чисел с учетом деления на 0. Вычислить:
а) 10/3
b) 10/0
Указание: Делитель в регистре BL. При делении на 0 выдать на экран соответствующее сообщение.
Вариант №8.(*)
Составить процедуру (тип NEAR) заполнения блока памяти из N слов рядом натуральных чисел. Если число делится на 4 то вместо него заносится 0.
Адрес начала блока в регистре ВХ
Вариант №9.
Написать процедуру выбора двух альтернатив (0 <= a <= 100, 0 <= b < 100)
;Если а <= b, то с=a * b
;если a > b, то c=a / b
Указание: ;а в регистре AL; ;b в регистре BL; ;c в регистре DX
Сегмент данных отсутствует.
Вычислить для: а) а=5, b=25; в) а=25, b=5
Вариант №10.(*)
Поиск ненулевой ячейки в блоке памяти.
Составить программу, которая находит первый ненулевой элемент в заданном блоке памяти из пяти байтовых элементов. Смещение начального адреса блока берется из регистра ВХ; смещение конечного адреса блока берется из регистра DI.
Смещение адреса ненулевого байта возвращается в регистре ВХ. Если ненулевой байт ненайден, то на экран выдается сообщение.
Указание: использовать команду JNZ.
Вариант №11.
Пересылка блоков памяти.
Составить процедуру, которая пересылает блок памяти длиной N байт в такой же блок. Смещение начального адреса первого блока берется из регистра SI; смещение начального адреса второго блока берется из регистра DI; N в регистре СХ
Указание: Использовать команду JCXZ.
Вариант №12.
Пересылка блоков памяти.
Составить процедуру, которая пересылает блок памяти длиной N байт в такой же блок. Смещение начального адреса первого блока берется из регистра SI; смещение начального адреса второго блока берется из регистра DI; N в регистре СХ
Указание: Использовать команду JNZ.
Вариант №13. (*)
Написать процедуру, которая размещает два 16-битных числа без знака в памяти в порядке убывания (меньшее число заносится в ячейку с старшим адресом).
Результат: Смещение адреса первого числа берется из регистра ВХ; смещение адреса второго числа - из регистра DI
Вариант №14.
Дано: (0 <= a < 2000, 0 <= b < 2000)
Написать процедуру, которая осуществляет выбор:
Если а < b, то с=b - a;
если a = b, то c=b;
если a > b, то c=a + b
Вариант №15.
Дано: (20 <= z < 200)
Написать процедуру, которая осуществляет выбор:
;Если z < 20, то c=z + 20
;если z = 20, то c=z/20 (частное)
;если z > 20, то c=z - 20
Вариант №16.(*)
Поиск нулевой ячейки в блоке памяти.
Составить программу, которая находит первый нулевой элемент в заданном блоке памяти из восьми байтовых элементов. Смещение начального адреса блока берется из регистра ВХ; смещение конечного адреса блока берется из регистра DI.
Смещение адреса нулевого байта возвращается в регистре ВХ. Если нулевой байт ненайден, то по возвращении в регистре ВХ будет содержаться то же значение, что и в DI
Указание: использовать команду JZ.
Вариант №17(*).
Преобразование регистра символов.
Написать программу, которая производит замену в строке символов длиной n байт больших букв латинского алфавита на малые.
Указание: Строчным буквам в таблице ASCII соответствует диапазон кодов 61h-7ah, а прописным – 41h-5ah. Для составления оптимального алгоритма необходимо сравнить представление соответствующих прописных и строчных букв в двоичном виде:
a – 0110 0001……z – 0111 1010
A – 0100 0001…..Z – 0101 1010
Вариант №18.(*)
Составить программу, которая производит подсчет количества ненулевых элементов в области blok длиной n байт.
Указание: использовать команды LOOP, JCXZ, CMP, JE.
На выходе в AL – количество ненулевых элементов.
Вариант №19.(**)
Составить процедуру, которая производит деление двух беззнаковых чисел с учетом деления на 0. Вычислить:
а) 300000/300
b) 300000/0
Указание: Делитель в регистре BХ. При делении на 0 выдать на экран соответствующее сообщение.
Вариант №20.(**)
Составить процедуру (тип NEAR) заполнения блока памяти из 10 байт рядом квадратов натуральных чисел. Если квадрат числа делится на 8 то вместо него заносится символ «а».
Вариант №21.
Написать процедуру выбора двух альтернатив (0 <= a <= 100, 0 <= b < 100)
;Если а <= b, то с=a + b
;если a > b, то c=a - b
Указание: ;а в регистре AL; ;b в регистре BL; ;c в регистре DX.
Сегмент данных отсутствует.
Вычислить для: а) а=5, b=25; в) а=25, b=5
Вариант №22.(*)
Поиск нулевой ячейки в блоке памяти.
Составить программу, которая находит первый нулевой элемент в заданном блоке памяти из пяти байтовых элементов. Смещение начального адреса блока берется из регистра ВХ; смещение конечного адреса блока берется из регистра DI.
Смещение адреса нулевого байта возвращается в регистре ВХ. Если нулевой байт ненайден, то на экран выдается сообщение.
Указание: использовать команду JZ.
Вариант №23.
Пересылка блоков памяти.
Составить процедуру, которая пересылает блок памяти длиной N байт в такой же блок. Смещение начального адреса первого блока берется из регистра SI; смещение начального адреса второго блока берется из регистра DI; N в регистре СХ
Указание: Использовать команду LOOP.
Вариант №24.
Вычислить значение функции:
(a-b)/a+1, если a > b,
Y= 25, если a = b,
(a-5)/b, если a < b,
ЛАБОРАТОРНАЯ РАБОТА №6
Цель работы: изучить правила работы с командой Ассемблера XLAT.
Теоретическая часть
Команда XLAT (кодирование AL )
XLAT [адрес_таблицы_перекодировки]
Логика: AL = (BX)+(AL)
Команда XLAT переводит байт, согласно таблице преобразований. Указатель 256-байтовой таблицы преобразований находится в BX. Байт, который нужно перевести, расположен в AL. После выполнения команды XLAT байт в AL заменяется на байт, смещенный на AL байтов от начала таблицы преобразований.
Таблица преобразований может содержать менее 256 байтов. Операнд, т.е. адрес_таблицы_перекодировки, является необязательным, поскольку указатель таблицы должен быть загружен в BX еще до начала выполнения команды.
Следующий пример иллюстрирует перевод десятичного числа (от 0 до 15) в соответствующую "цифру" шестнадцатеричной системы счисления:
Сегмент данных:
HEX_TABLE DB '0123456789ABCDEF'
Сегмент кода:
LEA BX,HEX_TABLE ;указатель таблицы засылаем в BX,
MOV AL,DECIMAL_DIGIT ;а переводимую цифру - в AL
XLAT HEX_TABLE ;переводим
. ;теперь в AL находится ASCII-код
. ;соответствующей цифры
. ;шестнадцатеричной системы
Выполнение лабораторной работы
Задача: Необходимо ввести с клавиатуры двузначное шестнадцатеричное число и, используя таблицу перекодировки, перевести его в двоичное и десятичное.
Для шестнадцатеричных цифр имеются следующие правила кодировки (табл. 4.1).
Символ шестнадцатиричной цифры |
ASCII-код (двоичное представление) |
Двоичная тетрада |
0 |
30h (0011 0000) |
0000 |
1 |
31h (0011 0001) |
0001 |
2 |
32h (0011 0010) |
0010 |
3 |
33h (0011 0011) |
0011 |
4 |
34h (0011 0100) |
0100 |
5 |
35h (0011 0101) |
0101 |
6 |
36h (0011 0110) |
0110 |
7 |
37h (0011 0111) |
0111 |
8 |
38h (0011 1000) |
1000 |
9 |
39h (0011 1001) |
1001 |
A,a |
41h (0100 0001) , 61h (0110 0001) |
1010 |
B,b |
42h (0100 0010) , 61h (0110 0010) |
1011 |
C,c |
43h (0100 0011) , 61h (0110 0011) |
1100 |
D,d |
44h (0100 0100) , 61h (0110 0100) |
1101 |
E,e |
45h (0100 0101) , 61h (0110 0101) |
1110 |
F,f |
46h (0100 0110) , 61h (0110 0110) |
1111 |
Для решения поставленной задачи нам, в первую очередь, необходимо составить таблицу перекодировки (tab1 в листинге 4.1).
Листинг 4.1.
PAGE 60,132
TITLE Лабораторная работа №4
;Программа преобразования двузначного шестнадцатеричного числа
;в десятичное представление с использованием команды XLAT
;Вход: исходное шестнадцатеричное число; вводится с клавиатуры
;Выход: результат преобразования в регистре AL
;-------Сегмент данных---------------------
DATASG SEGMENT PARA 'Data'
message DB "Введите две шестнадцатиричные цифры,$"
tab1 DB 30h dup (0),0,1,2,3,4,5,6,7,8,9, 7h dup (0)
DB 0ah,0bh,0ch,0dh,0eh,0fh, 1ah dup (0)
DB 0ah,0bh,0ch,0dh,0eh,0fh, 99h dup (0)
DATASG ENDS ;Конец сегмента данных
;------------------------Сегмент стека---------------------
STK SEGMENT STACK
DB 256 DUP ('?') ;сегмент стека
STK ENDS ;Конец сегмента стека
;------------------------Сегмент кода---------------------
CODE SEGMENT PARA PUBLIC 'CODE'
MAIN PROC FAR ;начало процедуры MAIN
ASSUME CS:CODE, DS:DATASG, SS:STK
MOV AX,DATASG ;адрес сегмента данных в регистр АХ
MOV DS,AX ;AX в DS
………………………………………………
MOV AX,4C00h ;завершение работы программы
int 21h ;вызов DOS
MAIN ENDP ;конец процедуры MAIN
CODE ENDS ;конец сегмента кода
END MAIN ;конец программы с точкой входа MAIN
Обсудим этот момент подробнее. Прежде всего нужно определится со значениями тех байтов, которые вы будете изменять. В нашем случае это символы шестнадцатиричных цифр. Поэтому мы конструируем в сегменте данных таблицу, в которой на места байтов, соответствующих символам шестнадцатиричных цифр, помещаем их новые значения, то есть двоичные эквиваленты шестнадцатиричных цифр. Например: для ASCII-кода шестнадцатиричной цифры ‘В’ его значение должно стоять на 66(42h) месте в таблице tab1.
Строки 10-12 листинга 4.1 демонстрируют, как это сделать. Байты этой таблицы, смещения которых не совпадают со значениями кодов шестнадцатиричных цифр, нулевые. Действительно, до 30h (48) ASCII-кодов нет (см. табл.4.1) и у нас стоят нули (30h dup (0)). Следует учесть, что до 30h (48) номера таблицы именно 48 нолей, так как нумерация начинается с 0. Дальше от 30h до 39h идут шестнадцатиричные цифры 0 .. 9. Затем до 41h символов нет. Это составляет: 41h - 39h = 7h=7D нулей. Далее от 41h до 46h идут большие буквы от ‘А’ до ‘F’. Далее 61h - 41h = 1Ah=26 нулей и от 61h до 66h малые буквы от ‘a’ до ‘f’. И большие и маленькие буквы имеют одно и то же двоичное значение (например, ‘A’ и ‘a’ имеют одно и то же значение 0ah = 0000 1010). Желательно определить все 256 байт таблицы. Дело в том, что если мы ошибочно поместим в AL код символа, отличный от символа шестнадцатиричной цифры, то после выполнения команды XLAT получим непредсказуемый результат. В случае листинга 4.1 это будет ноль, что не совсем корректно, так как непонятно, что же в действительности было в AL: код символа «0» или что-то другое. Поэтому, наверное, есть смысл здесь поставить «защиту от дурака», поместив в неиспользуемые байты таблицы какой-нибудь определенный символ (например ?). После каждого выполнения XLAT нужно просто будет контролировать значение в AL на предмет совпадения с этим символом, и если оно произошло, выдавать сообщение об ошибке.
После того как таблица составлена, с ней можно работать. В сегменте команд, после обычной процедуры загрузки адреса сегмента данных в регистр DS (строки 22-23), командой LEA загружаем адрес таблицы в регистр ВХ (<24>). Просмотрите это в отладчике с помощью окна Watches и дампа распределения памяти Dump. Далее, в строках 25-27 выводим на экран приглашение к вводу шестнадцатеричных цифр. Для этого в регистр AH помещаем номер функции DOS 9 (09h-вывод строки символов на дисплей), в регистр DX адрес строки message и вызываем прерывание 21h. Очищаем регистр АХ и помещаем в АН номер функции 01h (ввод символа с клавиаторы) и прерывание 21h. После выполнения функции 01h в регистре AL будет введеный символ (проверьте это с помощью отладчика). Команда XLAT по номеру ВХ+AL определит в таблице двоичное значение первого введенного символа. Он будет иметь вид 0nh (или 0000 nnnn в двоичном виде, т.е. старший полубайт будет равен нулю). Младший полубайт необходимо где-то запомнить. Для этого мы пересылаем его в регистр DL (<32>) и сдвигаем на 4 разряда влево (<33>), подготавливая место для следующей цифры. В DL будет (nnnn 0000). Далее вызываем 21h (<35>) для ввода второго символа в AL (в АН по-прежнему находится 1h). После XLAT (<36>) в AL будет (0000 mmmm). Складывая AL и DL, получим в AL окончательный результат (nnnn mmmm). Его можно посмотреть при помощи отладчика.
Для закрепления знаний и исследования трудных моментов выполните программу из листинга 4.1 под управлением отладчика.