Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Абель.docx
Скачиваний:
13
Добавлен:
26.11.2018
Размер:
569.84 Кб
Скачать

Inc/dec di ;Инкремент или декремент

UNC/DEC SI ;Инкремент или декремент

LOOP LABEL1

LABEL2: ...

В программе на рис.11.1 процедура C10MVSB использует команду MOVSB

для пересылки содержимого десятибайтового поля NAME1 в поле NAME2. Первая

команда CLD сбрасывает флаг направления в 0 для обеспечения процесса

пересылки слева направо. В нормальном состоянии флаг DF обычно имеет

нулевое значение и команда CLD используется из предосторожности.

__________________________________________________________________________

page 60,132

TITLE STRING (EXE) Проверка строковых операций

; ---------------------------------------------------

STACKSG SEGMENT PARA STACK 'Stack'

DW 32 DUP(?)

STACKG 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 ;Подпрограмма MVSB

CALL D10MVSW ;Подпрограмма LODS

CALL E10LODS ;Подпрограмма LODS

CALL F10STOS ;Подпрограмма CMPS

CALL H10SCAS ;Подпрограмма SCAS

RET

BEGIN ENDP

; Использование MOVSB:

; -------------------

C10MVSB PROC NEAR

CLD

LEA SI,NAME1

LEA D1,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 ;Загрузить первое слово

LODSW ; из NAME1 в AX

RET

E10LODS ENDP

; Использование STOSW:

; -------------------

F10STOS PROC NEAR

CLD

LEA D1,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

CODES ENDS

END BEGIN

__________________________________________________________________________

Рис.11.1. Использование цепочечных команд.

Две команды LEA загружают регистры SI и DI относительными адресами

NAME1 и NAME2 соответственно. Так как регистры DS и ES были ранее

инициализированы адресом DATASG, то полные адреса полей NAME1 и NAME2

будут в регистрах ES:DI и DS:SI. (COM программа автоматически

инициализирует регистры ES и DS). Команда MOV заносит в регистр CX

значение 10 - длину полей NAME1 и NAME2. Команда REP MOVSB выполняет

следующее:

- Пересылает самый левый байт из поля NAME1 (адресованного

pегистрами ES:DI) в самый левый байт поля NAME2 (адресованного

регистрами DS:SI).

- Увеличивает на 1 адреса в регистрах DI и SI для следующего

байта.

- Уменьшает CX на 1.

- Повторяет перечисленные действия (в данном случае 10 раз),

пока содержимое регистра CX не станет равным нулю.

Поскольку флаг DF имеет нулевое значение, команда MOVSB увеличивает

адреса в регистрах DI и SI, и в каждой итерации процесс переходит на байт

вправо, т.е. пересылает байт из NAME1+1 в NAME2+1 и т.д. Если бы флаг DF

был равен 1, тогда команда MOVSB уменьшала бы адреса в регистрах DI и SI,

выполняя процесс справа налево. Но в этом случае регистры SI и DI

необходимо инициализировать адресами последних байтов полей, т.е. NAME1+9

и NAME2+9 соответственно.

В процедуре D10MVSW (рис.11.1) используется команда MOVSW,

пересылающая одно слово за одно выполнение. Так как команда MOVSW

увеличивает адреса в регистрах DS и SI на 2, операция требует только пять

циклов. Для процесса пересылки справа налево регистр SI должен быть

инициализирован адресом NAME1+8, а регистр DI - NAME2+8.

LODS: ЗАГРУЗКА СТРОКИ

________________________________________________________________

Команда LODS загружает из памяти в регистр AL один байт или в регистр

AX одно слово. Адрес памяти определяется регистрами DS:SI. В зависимости

от значения флага DF происходит увеличение или уменьшение регистра SI.

Поскольку одна команда LODS загружает регистр, то практической пользы

от префикса REP в данном случае нет. Часто простая команда MOV полностью

адекватна команде LODS, хотя MOV генерирует три байта машинного кода, а

LODS - только один, но требует инициализацию регистра SI. Можно

использовать команду LODS в том случае, когда требуется продвигаться вдоль

строки (по байту или по слову), проверяя загружаемый регистр на конкретное

значение.

Команды, эквивалентные команде LODSB:

MOV AL,[SI]

INC SI

На рис.11.1 процедура E10LODS демонстрирует использование команды

LODSW. В примере обрабатывается только одно слово: первый байт из области

NAME1 (содержащий As) заносится в регистр AL, а второй байт - в регистр

AH. В результате в регистре AX получится значение sA.

STOS: ЗАПИСЬ СТРОКИ

________________________________________________________________

Команда STOS записывает (сохраняет) содержимое регистра AL или AX в

байте или в слове памяти. Адрес памяти всегда представляется регистрами

ES:DI. В зависимости от флага DF команда STOS также увеличивает или

уменьшает адрес в регистре DI на 1 для байта или на 2 для слова.

Практическая польза команды STOS с префиксом REP - инициализация

области данных конкретным значением, например, очистка дисплейного буфера

пробелами. Длина области (в байтах или в cловах) загружается в регистр AX.

Команды, эквивалентные команде REP STOSB:

JCXZ LABEL2

LABEL1: MOV [DI],AL