Транслирующая команда 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