- •МІнІстерство оСвІти і науКи УкраЇни
- •Двоичные числа
- •Шестнадцатеричные числа
- •1.2.4. Числа со знаком.
- •Знаковый бит
- •Дополнение до двух.
- •1.2. Представление данных.
- •00001001 (Инверсия бит)
- •Максимальные и минимальные значения
- •Лабораторная работа №2
- •Трансляция программы
- •Компоновка программы
- •Отладка программы
- •Лабораторная работа №3
- •Теоретическая часть Упрощенные директивы сегментации
- •I этап.
- •Лабораторная работа №4
- •Лабораторная работа №5
- •Лабораторная работа №7
- •Вариант №1. (*)
Лабораторная работа №7
Цель работы: изучить правила работы с цепочечными командами.
Примечание.
В контексте данной лабораторной работы под “строкой”, “текстом” и “словом” понимается набор латинских символов, кирилицы или цифр, оканчивающихся символом “$”.
Перед выполнением лабораторной работы необходимо тщательно разобрать пример. Прцедуры WrStr, BinToASCII и StrLen используются практически во всех выриантах.
Пример:
Заданы строки S1 и S2. Найти строку S = S1 + S2. ;Исходные строки, их длины и результат вывести на экран.
PAGE 60,132
TITLE Лабораторная работа №7.
; Пример
;Заданы строки S1 и S2. Найти строку S = S1 + S2.
;Исходные строки, их длины и результат вывести на экран.
;-------Сегмент данных---------------------
DATASG SEGMENT PARA 'Data'
;source DB 'Команды обработки строк$' ;Заданная строка
S1 DB 'Команды$' ;Заданная строка
S2 DB '555$' ;Заданная строка
len1 DW ? ;Длина строки S1
len2 DW ? ;Длина строки S2
text1 DB 'Строка S1: $'
text2 DB 'Строка S2: $'
text3 DB 'Длина строки S1: $'
text4 DB 'Длина строки S2: $'
text5 DB 'Полученная строка: $'
EndLine DB 13,10,'$' ;Конец строки
StrNum DB 8 DUP (?), '$'
DATASG ENDS ;Конец сегмента данных
;------------------------Сегмент стека---------------------
STK SEGMENT STACK
DB 256 DUP ('?') ;сегмент стека
STK ENDS ;Конец сегмента стека
;------------------------Сегмент кода---------------------
CODE SEGMENT PARA PUBLIC 'CODE'
BEGIN PROC FAR
ASSUME CS:CODE, DS:DATASG, ES:DATASG, SS:STK
MOV AX,DATASG
MOV DS,AX
MOV ES,AX ;настройка ES на DS
;-------------------Выводим строку S1--------------------
LEA DX,text1
CALL WrStr
LEA DX,S1
CALL WrStr
LEA DX,EndLine
CALL WrStr
;-------------------Выводим строку S2--------------------
LEA DX,text2
CALL WrStr
LEA DX,S2
CALL WrStr
LEA DX,EndLine
CALL WrStr
;------------------Определяем длину строки S1
LEA DI,S1 ;загрузка в es:DI смещения строки
CALL StrLen
MOV len1,DI
;-------------------Выводим длину строки S1--------------------
LEA DX,text3
CALL WrStr
MOV AX,len1
CALL BinToASCII
LEA DX,StrNum
CALL WrStr
LEA DX,EndLine
CALL WrStr
;------------------Определяем длину строки S2
LEA DI,S2 ;загрузка в es:DI смещения строки
CALL StrLen
MOV len2,DI
;-------------------Выводим длину строки S2--------------------
LEA DX,text4
CALL WrStr
MOV AX,len2
CALL BinToASCII
LEA DX,StrNum
CALL WrStr
LEA DX,EndLine
CALL WrStr
;------------------Соединяем строки S1 и S2------------------------
LEA SI,S2 ;начало S2 в SI
LEA DI,S1 ;начало S1 в DI
ADD DI,len1 ;конец S1
MOV CX,len2 ;CX=len2
INC CX ;СХ=len2+1(захватить $)
CLD ;сброс флага DF - обработка
;строки от начала к концу
REP MOVSB
;-------------------Выводим результирующую строку--------------------
LEA DX,text5
CALL WrStr
LEA DX,S1
CALL WrStr
LEA DX,EndLine
CALL WrStr
@@exit:
MOV AX,4c00h
INT 21H
BEGIN ENDP
;---------Процедура вывода строки на экран
WrStr PROC NEAR
;Адрес начала строки в регистре DX
PUSH AX
MOV AH,09h ;функция вывода строки на экран
INT 21h ;прерывание DOS
POP AX
RET
WrStr ENDP
;---------Процедура преобразования двоичного числа в ASCII-код
BinToASCII PROC NEAR
;Выводимое число в регистре AX
;Результат (строка) находится в переменной StrNum длиной 8 байт
PUSH CX DX SI
PUSH AX ;Сохраним число
LEA DI,StrNum ;Очищаем StrNum
MOV CX,8 ;в СХ длина StrNum
MOV AL,' ' ;заносим в AL пробел
CLD ;DF=0-обработка строки сначала в конец
REP STOS StrNum ;Пробелы в StrNum
POP AX ;Вернем число
MOV CX,0010 ;Фактор деления
LEA SI,StrNum+7 ;Адрес последнего символа строки
@@c20:
CMP AX,0010 ;Значение меньше 10?
JB @@c30 ;Да-выйти
XOR DX,DX ;Очистить часть частного
DIV CX ;Разделить на 10
OR DL,30h ;Перевести остаток в ASCII
MOV [SI],DL ;и записать в строку
DEC SI ;Уменьшить индекс
JMP @@c20 ; и вернуться на начало цикла
@@c30:
OR AL,30h ;Записать последнее частное
MOV [SI],AL ; как ASCII-символ
POP SI DX CX
RET
BinToASCII ENDP
;-------------------------Процедура определения длины строки, оканчивающейся $----------------
StrLen PROC NEAR
;->Адрес начала строки в ES:DI
;<-Длина строки в DI
PUSH AX CX
MOV AL,'$' ;символ для поиска - `$`
CLD ;сброс флага df
MOV CX,0FFFFh ;для префикса repne - длина строки (максимальная)
;поиск в строке (пока искомый символ и символ в строке не совпадут)
;выход при первом совпадении
REPNE SCASB
MOV DI,0FFFEh
SUB DI,CX ;max-CX = длине строки (без $)
POP CX AX
RET
StrLen ENDP
CODE ENDS
END BEGIN