Команды обработки строк
МЕТОДИЧЕСКИЕ УКАЗАНИЯ:
1. Для выполнения лабораторной работы вы должны войти в каталог группы из панели NORTON. Каждый студент должен иметь в каталоге группы свой личный каталог. Все программы должны создаваться и записываться в личном каталоге студента.
2. Для обработки строковых данных ассемблер имеет пять команд обработки строк:
MOVS переслать один байт или одно слово из одной области памяти в другую;
LODS загрузить из памяти один байт в регистр AL или одно слово в регистр АХ;
STOS записать содержимое регистра AL или АХ в память;
CMPS сравнить содержимое двух областей памяти размером в один байт или в одно слово;
SCAS сравнить содержимое регистра AL или АХ с содержимым памяти.
3. Префикс REP позволяет командам обработки строк обрабатывать строки любой длины.
4. Команды обработки строк могут записываться по 3 вариантам:
а) Запись команд с операндами:
MOVS DI,SI
LODS AL,SI или AX,SI
STOS DI,AL или DI,AX
CMPS SI,DI
SCAS DI,AL или DI,AX
б) Запись команд без операндов для обработки одного байта:
MOVSB
LODSB
STOSB
CMPSB
SCASB
в) Запись команд без операндов для обработки одного слова:
MOVSW
LODSW
STOSW
CMPSW
SCASW
5. Команды обработки строк предполагают, что регистры DI и SI содержат относительные адреса, указывающие на необходимые области памяти. Регистр SI обычно связан с регистром сегмента данных - DS:SI. Регистр DI всегда связан с регистром дополнительного сегмента - ES:DI.
ПОРЯДОК ВЫПОЛНЕНИЯ РАБОТЫ:
1. REP: префикс повторения команды.
1.1. Запишите в текстовом редакторе NORTON следующую программу в СОМ-формате(rep.asm):
.286 TITLE REP (COM) CODESG SEGMENT PARA 'Code'
ASSUME CS:CODESG,DS:CODESG,SS:CODESG,ES:CODESG
ORG 100H ;Начало в конце PSP
BEGIN: JMP MAIN ;Обход через данные
;-------------------------------------------------------
STRING1 DB 20 DUP('*')
STRING2 DB 20 DUP(' ')
;--------------------------------------------------------
MAIN PROC NEAR
CLD ;Сброс флага DF
MOV CX,20 ;Счетчик на 20 байт
LEA DI,STRING2 ;Адрес "куда"
LEA SI,STRING1 ;Адрес "откуда"
REP MOVSB ;Переслать данные
RET ;Вернуться в DOS
MAIN ENDP
CODESG ENDS
END BEGIN
Префикс REP обеспечивает повторение команды несколько раз. Для использования префикса REP необходимо установить начальное значение в регистре СХ. При выполнении цепочечной команды с префиксом REP происходит уменьшение на 1 значения в регистре СХ до нуля. Таким образом, можно обрабатывать строки любой длины.
Команда CLD устанавливает флаг DF в 0. Это обеспечивает направление пересылки данных из ячейки в ячейку слева направо. Для обеспечения пересылки данных справа налево необходимо использовать команду STD, устанавливающую флаг DF в 1, а в регистры DI и SI записать адреса STRING2+20 и STRING1+19 соответственно.
В программе осуществляется пересылка 20 байт из области памяти STRING1 в область памяти STRING2.
1.2. Выполнить ассемблирование и компоновку программы. Листинг программы записать в отчет.
1.3. Вызвать отладчик DEBUG для выполнения программы. Просмотреть сегмент кодов командой отладчика D CS:100 и выполнить трассировку программы до команды RET. Повторить просмотр сегмента кодов командой D CS:100 , объяснить изменения произошедшие в сегменте кодов и записать выводы в отчет.
2. Программа: строковые операции.
2.1. Запишите в текстовом редакторе NORTON следующую программу в ЕХЕ-формате(string.asm):
286 TITLE STRING (EXE) Строковые операции
;----------------------------------------------
STACKSG SEGMENT PARA STACK 'Stack'
DW 32 DUP(?)
STACKSG ENDS
;-----------------------------------------------
DATASG SEGMENT PARA 'Data'
NAME1 DB 'Assemblers' ;Элементы данных
NAME2 DB 10 DUP(' ')
NAME3 DB 10 DUP(' ')
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
CALL C10MVSB
CALL D10MVSW ;Подпрограмма MVSB
CALL E10LODS ;Подпрограмма MVSW
CALL F10STOS ;Подпрограмма LODS
CALL G10CMPS ;Подпрограмма CMPS
CALL H10SCAS ;Подпрограмма SCAS
RET
BEGIN ENDP
; Использование MOVS
; ------------------
C10MVSB PROC NEAR
CLD
LEA SI,NAME1
LEA DI,NAME2
MOV CX,10 ;Переслать 10 байтов
REP MOVSB ;из NAME1 в NAME2
RET
C10MVSB ENDP
; Использование MOVSW
; -------------------
D10MVSW PROC NEAR
CLD
LEA SI,NAME2
LEA DI,NAME3
MOV CX,05 ;Переслать 5 слов
REP MOVSW ;из NAME2 в NAME3
RET
D10MVSW ENDP
; Использование LODSW
; -------------------
E10LODS PROC NEAR
CLD
LEA SI,NAME1 ;Загрузить 1 4-е 0 слово
LODSW ; из NAME1 в АХ
RET
E10LODS ENDP
; Использование STOSW
; -------------------
F10STOS PROC NEAR
CLD
LEA DI,NAME3
MOV CX,05
MOV AX,2020H ;Переслать пробелы
REP STOSW ;в NAME3
RET
F10STOS ENDP
; Использование CMPSB
; -------------------
G10CMPS PROC NEAR
CLD
MOV CX,10
LEA SI,NAME1
LEA DI,NAME2
REPE CMPSB ;Сравн. NAME1 и NAME2
JNE G20 ;Не равны?
MOV BH,01
G20: MOV CX,10
LEA SI,NAME2
LEA DI,NAME3
REPE CMPSB ;Сравн. NAME2 и NAME3
JE G30 ;Если равны, то выйти
MOV BL,02
G30: RET
G10CMPS ENDP
; Использование SCASB
; -------------------
H10SCAS PROC NEAR
CLD
MOV CX,10
LEA DI,NAME1
MOV AL,'m' ;Поиск символа 'm'
REPNE SCASB ; в NAME1
JNE H20 ;Если нет - выйти
MOV AH,03
H20: RET
H10SCAS ENDP
CODESG ENDS
END BEGIN
Процедура C10MVSB использует команду MOVSB для пересылки содержимого десятибайтового поля NAME1 в поле NAME2. Первая команда CLD сбрасывает флаг направления в 0 для обеспечения процесса пересылки слева направо. Две команды LEA загружают регистры SI и DI относительными адресами NAME1 и NAME2 соответственно. Команда MOV заносит в регистр СХ значение 10 - длину полей NAME1 и NAME2. Команда REP MOVS выполняет следующее: а) пересылает самый левый
байт поля NAME1 в самый левый байт NAME2, б) увеличивает на 1 адреса в регистрах DI и SI для следующего байта, в) уменьшает СХ на 1, г) повторяет перечисленные действия (в данном случае 10 раз), пока содержимое регистра СХ не станет равным нулю.
В процедуре D10MVSW используется команда MOVSW, пересылающая одно слово за одно выполнение. Так как команда MOVSW увеличивает адреса в регистрах DI и SI на 2, операция требует только пять
циклов.
Процедура E10LODS демонстрирует использование команды LODS. По этой команде обрабатывается только одно слово: первый байт из области NAME1 заносится в регистр AL, а второй байт - в регистр АН.
Процедура F10STOS демонстрирует использование команды STOSW. Операция осуществляет запись пробелов (2020) пять раз в область NAME3.
В процедуре G10CMPS команда CMPS сравнивает содержимое одной области памяти с содержимым другой области. В зависимости от флага DF команда CMPS также увеличивает или уменьшает адреса в регистрах SI и DI на 1 для байта или на 2 для слова. Команда CMPS устанавливает флаг ZF (ZR - 1 если равно, NZ - 0 если не равно). При использовании префикса REP в регистре СХ должно находиться
значение длины сравниваемых полей. Команда CMPS может сравнивать любое число байтов или слов. Использование префикса REPE (REPZ) означает прекращение выполнения команды CMPS сразу же после первого сравнения с результатом "не равно".
В процедуре H10SCAS команда SCAS сканирует (просматривает) строку на определенное значение байта или слова. Команда SCAS сравнивает содержимое области памяти NAME1 с содержимым регистра AL. В зависимости от значения флага DF команда SCAS также увеличивает или уменьшает адрес в регистре DI на 1 для байта или на 2 для слова. Команда SCAS устанавливает флаг ZF (ZR - 1 если прове-
ряемый символ соответствует символу в области памяти). Префикс REPNE(REPNZ) обеспечивает повторение команды SCAS до тех пор пока результатом сканирования будет "не равно". Как только будет получен результат "равно", флаг ZF будет установлен в 1 (ZR). При использовании префикса REP и значения длины в регистре СХ команда SCAS может сканировать строки любой длины.
2.2. Выполнить ассемблирование и компоновку программы. Листинг программы записать в отчет.
2.3. Вызвать отладчик DEBUG для выполнения программы string.exe. Выполнить трассировку до команды CALL C10MVSB. Просмотреть сегмент данных введя команду D DS:00 и продолжить трассировку, выполнив команду REP MOVSB пять раз. Снова просмотреть сегмент данных, и продолжить трассировку до следующей процедуры D10MVSW. Выводы записать в отчет.
2.4. Продолжить трассировку, выполнив команду REP MOVSW три раза. Снова просмотреть сегмент данных, и продолжить трассировку до следующей процедуры E10LODS. Выводы записать в отчет.
2.5. Продолжить трассировку до следующей процедуры F10STOS. Определить какие изменения произошли в регистре АХ. Выводы записать в отчет.
2.6. Продолжить трассировку до следующей процедуры G10CMPS. Просмотреть сегмент данных. Выводы записать в отчет.
2.7. Продолжить трассировку до следующей процедуры H10SCAS. Объяснить, как выполняются команды: CMPSB, JNE и JE. Объяснить изменения, происходящие в регистре ВХ и изменение флага ZF. Выводы записать в отчет.
2.8. Продолжить трассировку до конца программы. Объяснить изменения в регистрах АХ и СХ, а также изменения флага ZF. Выводы записать в отчет. Выйти из отладчика.