Транслирующая команда xlat
4.1. Записать в текстовом редакторе NORTON следующую программу в СОМ-формате:
.286
TITLE XLATE (COM) Перевод ASCII в EBCDIC
CODESG SEGMENT PARA 'Code'
ASSUME CS:CODESG,DS:CODESG,SS:CODESG,ES:CODESG
ORG 100H ;Начало в конце PSP
BEGIN: JMP MAIN ;Обход через данные
;-------------------------------------------------------
ASCNO DB '-31.5 ' ;Элементы данных
EBCNO DB 6 DUP(' ')
XLTAB DB 45 DUP(40H)
DB 60H,2DH
DB 5CH
DB 0F0H,0F1H,0F2H,0F3H,0F4H
DB 0F5H,0F6H,0F7H,0F8H,0F9H
DB 199 DUP(40H)
;--------------------------------------------------------
MAIN PROC NEAR
LEA SI,ASCNO ;Адрес символов ASCNO
LEA DI,EBCNO ;Адрес поля EBCNO
MOV CX,06 ;Длина
LEA BX,XLTAB ;Адрес таблицы
A20: MOV AL,[SI] ;Получить ASCII-символ
XLAT ;Перекодировка
MOV [DI],AL ;Записать в поле EBCNO
INC DI
INC SI
LOOP A20 ;Повторить 6 раз
RET
MAIN ENDP
CODESG ENDS
END BEGIN
Для выполнения команды XLAT адрес таблицы заносится в регистр ВХ, транслируемый байт из поля ASCNO заносится в регистр AL.
Команда XLAT использует значение в регистре AL в качестве относительного адреса в таблице, т.е. складывает адрес в ВХ и смещение в AL. Первый байт поля ASCNO содержит ASCII-код знака минус 45(2DH). Адрес байта в таблице будет XLTAB+45. Этот байт содержит значение 60Н(код знака минус в формате EBCDIC). Число 60Н команда XLAT загружает в регистр AL.
Второй байт поля ASCNO содержит ASCII-код числа 3 - 51(33Н). Адрес байта в таблице будет XLTAB+51. Этот байт содержит значение 0F3H(код числа 3 в формате EBCDIC). Число 0F3H команда XLAT загружает в регистр AL во втором цикле работы программы.
В программе организован цикл для обработки шестибайтового поля. Поле ASCNO в начале выполнения программы содержит значение -31.5 с последующим пробелом, или 2D33312E3520(в формате ASCII). В конце выполнения программы в поле EBCNO должно быть 60F3F12DF540(в формате EBCDIC).
4.2. Выполнить ассемблирование и компоновку программы. Листинг программы записать в отчет.
4.3. Вызвать отладчик DEBUG на выполнение программы. Просмотреть сегмент кодов перед трассировкой программы. Выполнить трассировку программы. Проверить сегмент кодов после выполнения программы. Выводы о выполнении программы записать в отчет. D
5. Программа: вывод шестнадцатиричных и ASCII-кодов.
5.1. Записать в текстовом редакторе NORTON следующую программу в СОМ-формате:
.286
TITLE ASCHEX (COM) Преобраз. ASCII в шест.
CODESG SEGMENT PARA 'Code'
ASSUME CS:CODESG,DS:CODESG,SS:CODESG,ES:CODESG
ORG 100H ;Начало в конце PSP
BEGIN: JMP MAIN ;Обход через данные
;-------------------------------------------------------
DISPROW DB 20 DUP(' '),13 ;4 пробела
HEXSTR DB 00
XLATAB DB 30H,31H,32H,33H,34H
DB 35H,36H,37H,38H,39H
DB 41H,42H,43H,44H,45H,46H
;--------------------------------------------------------
MAIN PROC NEAR ;Основная процедура
CALL Q10CLR ;Очистить экран
LEA SI,DISPROW
A20: CALL C10HEX ;Перекодировать
CALL D10DISP ;и вывести на экран
CMP HEXSTR,0FFH ;Последнее знач.?
JE A50 ;Да - завершить
INC HEXSTR ;Нет - перейти
JMP A20 ;к следующему
A50: RET
MAIN ENDP
; Перекодировка в шест.
; ---------------------
C10HEX PROC NEAR
MOV AH,00
MOV AL,HEXSTR ;Получить шест. пару
MOV CL,04 ;Уст. величину сдвига
SHR AX,CL ;Сдвиг правой ш. цифры
LEA BX,XLATAB ;Уст. адрес таблицы
XLAT ;Перекодировка в шест.
MOV [SI],AL ;Записать левый символ
MOV AL,HEXSTR
SHL AX,CL ;Сдвиг левой цифры
SHR AL,CL
XLAT ;Перекодировка в шест.
MOV [SI]+1,AL ;Записать пр. символ
RET
C10HEX ENDP
; Вывод на экран
; --------------
D10DISP PROC NEAR
MOV AL,HEXSTR
MOV [SI]+3,AL
CMP AL,1AH ;Символ E0F?
JE D20 ;Да - обойти
CMP AL,07H ;Меньше/равно 07?
JB D30 ;Да - ОК
CMP AL,10H ;Больше/равно 0F?
JAE D30 ;Да - ОК
D20: MOV BYTE PTR [SI]+3,20H
D30: ADD SI,05 ;След. элемент в строке
LEA DI,DISPROW+80
CMP DI,SI
JNE D40
MOV AH,40H ;Ф-ция вывода на экран
MOV BX,01 ;Номер устройства
MOV CX,81 ;Вся строка
LEA DX,DISPROW
INT 21H
LEA SI,DISPROW ;Начальный адрес строки
D40: RET
D10DISP ENDP
; Очистка экрана
; --------------
Q10CLR PROC NEAR
MOV AX,0600H
MOV BH,03 ;Цвет (07 для ч/б)
MOV CX,0000
MOV DX,184FH
INT 10H
RET
Q10CLR ENDP
CODESG ENDS
END BEGIN
Программа отображает на экране почти все ASCII-символы, а также из шестнадцатиричные значения. Например, ASCII-символ для 53Н - это буква S. Полное изображение на экране выглядит в виде матрицы 16х16.
Отображение ASCII-символов осуществляется без особых проблем. Отображение шестнадцатиричных значений в символах ASCII более сложный процесс. Например для вывода на экран в коде ASCII шестнадцатиричных 00, 01 и т.д. необходимо преобразовать 00 в 3030, 01 в 3031 и т.д.
В программе начальное значение поля HEXSTR равно 00 и оно последовательно увеличивается на 1. Процедура C10HEX расщепляет байт HEXSTR на две шестнадцатиричные цифры. Предположим, что байт HEXSTR содержит 4F. Процедура сначала выделяет шестнадцатиричную цифру 4 и использует это значение для перекодировки по таблице XLATAB. В регистре AL устанавливается в результате значение 34. Затем процедура выделяет вторую шестнадцатиричную цифру F и перекодирует ее в 46. В результате обработки получается 3446, что
отображается на экране как 4F.
Программа записывает в поле DISPROW ASCII-коды и шестнадцатиричные коды. Из поля DISPROW информация выводится на дисплей, причем ASCII-код позволяет получить на экране дисплея шестнадцатиричные числа, а шестнадцатиричные коды воспринимаются дисплеем как ASCII-числа и выводятся в виде отдельных символов.
Программа предусматривает вывод пробелов для кодов 07Н-10Н, а также для кода 1АН, так как функция DOS воспринимает этот код как конец файла.
5.2. Выполнить ассемблирование и компоновку программы. Листинг программы записать в отчет.
5.3. Вызвать отладчик DEBUG на выполнение программы. Просмотреть сегмент кодов перед трассировкой программы. Выполнить трассировку программы до конца процедуры C10HEX и снова просмотреть сегмент кодов. Продолжить трассировку программы до конца процедуры D10DISP и повторить просмотр сегмента кодов. Закончить 1 цикл программы до повторного вызова процедуры C10HEX командой CALL. Аналогично проделать трассировку еще для 2 циклов выполнения
программы. Выводы о работе программы записать в отчет.
5.4. Определить по листингу программы относительный адрес команды INT 21H. Ввести команду отладчика G xxxx, где хххх - относительный адрес команды INT 21H. Просмотреть сегмент кодов перед выполнением команды INT 21H. Для выполнения команды INT 21H необходимо ввести команду отладчика G yyyy, где yyyy - адрес команды, следующей за командой INT 21H. Аналогично повторить выполнение
команды INT 21H 3 раза. Выводы о выводе информации на дисплей записать в отчет.
5.5. Запустить программу из панели NORTON. Просмотреть таблицу шестнадцатиричных кодов и соответствующих им символов на экране дисплея.
6. Программа: сортировка элементов таблицы.
6.1. Записать в текстовом редакторе NORTON следующую программу в ЕХЕ-формате:
.286
TITLE NMSORT (EXE) Ввод и сортировка имен
;----------------------------------------------
STACKSG SEGMENT PARA STACK 'Stack'
DW 32 DUP(?)
STACKSG ENDS
;-----------------------------------------------
DATASG SEGMENT PARA 'Data'
NAMEPAR LABEL BYTE ;Имя списка парам.
MAXNLEN DB 21 ;Макс. длина
NAMELEN DB ? ;Число введ. символов
NAMEFLD DB 21 DUP(' ') ;Имя
CRLF DB 13,10,'$'
ENDADDR DW ?
MESSG1 DB 'Name?','$'
NAMECTR DB 00
NAMETAB DB 30 DUP(20 DUP(' ')) ;Таблица имен
NAMESAV DB 20 DUP(?),13,10,'$'
SWAPPED DB 00
DATASG ENDS
;------------------------------------------------
CODESG SEGMENT PARA 'Code'
BEGIN PROC FAR ;Основная процедура
ASSUME CS:CODESG,DS:DATASG,SS:STACKSG,ES:DATASG
PUSH DS
SUB AX,AX
PUSH AX
MOV AX,DATASG
MOV DS,AX
MOV ES,AX
CLD
LEA DI,NAMETAB
CALL Q10CLR ;Очистить экран
CALL Q20CURS ;Установить курсор А20
A20: CALL B10READ ;Ввести имя с клавиатуры
CMP NAMELEN,00 ;Есть еще имена?
JZ A30 ;Нет - идти на сортировку
CMP NAMECTR,30 ;Введено 30 имен?
JE A30 ;Да - идти на сортировку
CALL D10STOR ;Записать имя в таблицу
JMP A20
A30: CALL Q10CLR ;Конец ввода имен, очистить экран
CALL Q20CURS ;Установить курсор
CMP NAMECTR,01 ;Менее 2 имен?
JBE A40 ;Да - выйти
CALL G10SORT ;Сортировать имена
CALL K10DISP ;Вывести результат
A40: RET ;Завершить программу
BEGIN ENDP
; Ввод имен с клавиатуры
; ----------------------
B10READ PROC
MOV AH,09
LEA DX,MESSG1 ;Вывести текст запроса
INT 21H
MOV AH,0AH
LEA DX,NAMEPAR ;Ввести имя
INT 21H
MOV AH,09
LEA DX,CRLF ;Вывести CLRF
INT 21H
MOV BH,00 ;Очистить поле после имени
MOV BL,NAMELEN ;Получить счетный символ
MOV CX,21
SUB CX,BX ;Вычислить оставшуюся длину
B20: MOV NAMEFLD[BX],20H ;Пробел
INC BX
LOOP B20
RET
B10READ ENDP
; Запись имени в таблицу
; ----------------------
D10STOR PROC
INC NAMECTR ;Число имен в таблице
CLD
LEA SI,NAMEFLD
MOV CX,10
REP MOVSW ;Переслать имя в таблицу
RET
D10STOR ENDP
; Сортировка имен в таблице
; -------------------------
G10SORT PROC
SUB DI,40 ;Установить адрес останова
MOV ENDADDR,DI
G20: MOV SWAPPED,00 ;Установить начало таблицы
LEA SI,NAMETAB
G30: MOV CX,20 ;Длина сравнения
MOV DI,SI
ADD DI,20 ;Следующее имя
MOV AX,DI
MOV BX,SI
REPE CMPSB ;Сравнить имя со следующим
JBE G40 ;Нет перестановки
CALL H10XCHG ;Перестановка
G40: MOV SI,AX
CMP SI,ENDADDR ;Конец таблицы?
JBE G30 ;Нет - продолжить
CMP SWAPPED,00 ;Есть перестан.?
JNZ G20 ;Да - продолжить
RET ;Нет - конец
G10SORT ENDP
; Перестановка элементов таблицы
; ------------------------------
H10XCHG PROC
MOV CX,10
LEA DI,NAMESAV
MOV SI,BX
REP MOVSW ;Сохранить меньший элемент
MOV CX,10
MOV DI,BX
REP MOVSW ;Переслать больший элемент на место меньшего
MOV CX,10
LEA SI,NAMESAV
REP MOVSW; Переслать сохраненный элемент на место большего
MOV SWAPPED,01 ;Признак перестановки
RET
H10XCHG ENDP
; Вывод на экран отсорт. имена
; ----------------------------
K10DISP PROC
LEA SI,NAMETAB
K20: LEA DI,NAMESAV ;Начальный адрес таблицы
MOV CX,10
REP MOVSW
MOV AH,09
LEA DX,NAMESAV
INT 21H ;Вывести на экран
DEC NAMECTR ;Это последний элемент?
JNZ K20 ;Нет - повторить цикл
RET ;Да - выйти
K10DISP ENDP
; Очистка экрана
; --------------
Q10CLR PROC
MOV AX,0600H
MOV BH,61H ;Цвет (07 для ч/б)
SUB CX,CX
MOV DX,184FH
INT 10H
RET
Q10CLR ENDP
; Установка курсора
; -----------------
Q20CURS PROC
MOV AH,02
SUB BH,BH
SUB DX,DX ;Установить курсор в 0
INT 10H
RET
Q20CURS ENDP
CODESG ENDS
END BEGIN
Программа обеспечивает ввод с клавиатуры до 30 имен, сортировку введенных имен в алфавитном порядке и вывод на экран отсортированного списка имен.
6.2. Выполнить ассемблирование и компоновку программы. Листинг программы записать в отчет.
6.3. Запустить программу из панели NORTON. Выводы о работе программы записать в отчет.
СОДЕРЖАНИЕ ОТЧЕТА:
1. Листинги программ.
2. Выводы о работе программ.
КОНТРОЛЬНЫЕ ВОПРОСЫ:
1. Определите таблицу, содержащую 3 символьных значения - JANV,FEVR,MART.
Составьте команды для получения адреса второго элемента таблицы символьных значений FEVR в регистре SI по правилу прямого табличного доступа.
2. Определите таблицу, содержащую 3 числовых значения - 51,81,91.
Составьте команды для получения адреса элемента таблицы, имеющего значение 81 в регистре SI по правилу табличного поиска.
3. Определите таблицу, содержащую 3 символьных значения - JANV,FEVR,MART.
Составьте команды для получения адреса второго элемента таблицы FEVR в регистре SI по правилу табличного поиска с использованием сравнения строк.
4. Составить программу перекодировки десятичной цифры (от 0 до 9) в ASCII-код с использованием команды XLAT и таблицы перекодировки.
ОТВЕТЫ:
1. MONTAB DB 'JANV','FEVR','MART'
LEA SI,MONTAB
MOV AL,32H
XOR AL,30H
DEC AL
MUL 04
ADD SI,AL
2. COSTAB DB 51,81,91
MOV CX,03
A20: MOV AX,81
LEA SI,COSTAB
CMP AX,[SI]
JE A30
ADD SI,02
LOOP A20
A30: RET
3. MONTAB DB 'JANV','FEVR','MART'
STOKIN DB 'FEVR'
LEA SI,MONTAB
A20: MOV CX,04
LEA DI,STOKIN
REPE CMPSB
JE A30
ADD SI,CX
JMP A20
A30: RET
4. ASCNO DB 8
EBCNO DB DUP(' ')
XLTAB DB 30H,31H,32H,33H,34H
DB 35H,36H,37H,38H,39H
LEA SI,ASCNO
LEA DI,EBCNO
MOV CX,01
LEA BX,XLTAB
MOV AL,[SI]
XLAT
MOV [DI],AL