Обработка строк байтов и слов
movs – пересылка строки
cmps – сравнение строк
scas – поиск в строке заданного символа
lods – загрузить AX из строки
stos – запись в строку из AX
Регистры, участвующие в цепочечных командах:
MOVS DI,SI
LODS AL,SI или AX SI
STOS DI,AL или DI,AX
CMPS SI,DI
SCAS DI,AL или DI,AX
Регистр SI обычно связан с регистром сегмента данных – DS:SL.
Регистр DI всегда связан с регистром дополнительного сегмента – ES:DI
MOVS, STOS, CMPS и SCAS требуют инициализации регистра ES (обычно адресом в регистре DS).
REP: префикс повторения цепочечной команды
При выполнении команды с префиксом REP происходит уменьшение на 1 значение в регистре CX до нуля
REP – повторять операцию, пока CX не равно 0
Пример: пересылка строки
STRL DB ‘режим’ ; исходная строка
STRLEN EQU $-STRL ; длина строки в байтах
TEXT DB 80 DUP (‘ ’) ; приемная строка
MOV CX,STRLEN ; пересылаем кол-во байт в CX
PUSH DS ; адрес сегмента данных в стек
POP ES ; настроили доп.сегмент
LEA SI,STRL ; адрес строки-источника загрузили в DI
LEA DI,TEXT ; строка-приемник - DI
CLD ; очистка флага, DF = 0
REP MOVSB ; пересылаем строку побайтно
REP заставляет МП выполнить MOVSB количество раз из CX
Возможная запись:
(REP MOVS TEXT,STRL)
Пример 2. Выполняется пересылка 20 байт из STRING1 в STRING2
Предположим, что оба регистра DS и ES инициализированы адресом сегмента данных
STRING1 DB 20 DUP (‘*’)
STRING2 DB 20 DUP (‘ ’)
…
CLD ; сброс флага DF
MOV CX,20 ; счетчик на 20 байт
LEA DI,STRING2 ; адрес области «куда»
LEA,SI,STRING1 ; адрес области «откуда»
REP MOVSB
При выполнении команд CMPS и SCAS возможна установка флагов состояния, так чтобы операция могла прекратиться сразу после обнаружения необходимого условия
REPZ или REPE – повторять операцию, пока флаг ZF показывает «равно или ноль».
Прекратить операцию при флаге ZF, указывающему на не равно или не ноль или при CX = 0
REPNE или REPNZ – повторять операцию, пока флаг ZF показывает «не равно или не ноль».
Прекратить операцию при флаге ZF, указывающему на «равно или нуль» или при CX = 0
Пример 3: сравнение 2-х строк
PATT DB ‘stringlen’ ; строка для сравнения
PATTLEN EQU $-PATT ; адрес и длина известны
TEXT DB 80 DUP (? ) ; приёмный буфер
PUSH DS
POP ES
LEA SI,PATT
LEA DI,TEXT
MOV CX,PATTLEN
CLD
REPE CMPSB
REPE – повторять, пока не будет CX = 0 или пока не встретятся разные элементы ZF = 0
Пример 4: поиск в строке заданного символа
STR DB 128 DUP (?)
MOV AL,’ ‘
PUSH DS
POP ES
LEA DI,STR
MOV CX,128
REPNE SCASB
; поиск пробела в строке, если символ найден – флаг ZF (нуля) установится в 1. Если символ не найден, то флаг = 0. При этом просматривается кол-во байт в CX
JNE NOT ; уход на метку, если не нашли (при ZF = 0)
DEC DI ; если символ найден, уменьшаем DI, чтобы он указывал на адрес найденного байта (символа ‘ ’)
Пример 5:
CLD
LEA SI,NAME1 ; загрузить первое слово
LODSW ; из NAME1 в AX
Пример 6:
LEA DI,NAME3
MOV CX,05
MOV AX,2020h ; переслать пробелы
REP STOSW ; в NAME3
Переходы. Прямой короткий, прямой ближний
Команды перехода JMP:
1) Прямой короткий
Пример:
seg segment ‘code’
…………………..
jmp short cont
…………………..
cont: ……………………
seg: ends
2) Прямой ближний
Пример
seg segment ‘code’
…………………..
jmp cont ; (или jmp near ptr cont)
…………………..
cont: ……………………
………………………..
seg: ends
3) Прямой дальний
seg1 segment ‘code’
…………………..
jmp far prt cont
…………………..
seg1 ends
seg2 segment ‘code’
cont: ……………………
seg2: ends
4) Косвенный ближний
Пример
seg1 segment ‘code’
…………………..
jmp DS: constadr ; переход не на метку constadr, а по адресу, содержащемуся в нем
…………………..
seg1 ends
dat segment
constadr dw cont
dat ends
5) Косвенный дальний
Пример
seg1 segment ‘code’
…………………..
jmp DS: constadr
seg1 ends
seg2 segment ‘code’
…………………..
cont …….
seg ends
dat segment
contadr dd cont
………………
dat ends
Вызовы процедур
CALL – команда вызова процедуры
1) Прямой ближний
Пример
seg segment ‘code’
mymain proc
call sub
……………………………..
mymain endp
sub proc near
…………….
ret
sub endp
seg ends
2) Прямой дальний
Пример
3) Косвенный ближний
Пример
seg segment ‘code’
mymain proc
……………………………..
call word ptr subadr
……………………………..
mymain endp
sub proc near
…………….
ret
sub endp
seg ends
dat segment
…………………………
subadr dw sub
………………………….
dat ends
4) Косвенный дальний
Пример
seg segment ‘code’
mymain proc
call dword
……………………………..
mymain endp
sub proc near
…………….
ret
sub endp
seg ends
dat segment
…………………………
subadr dw sub
………………………….
dat ends
Варианты вызовов процедур
call word ptr [bx] – если в bx адрес процедуры
call word ptr [bx],[si] – если в bx адрес таблицы адресов процедур, а в si – номер конкретной процедуры
call word ptr table [si] – если table – адрес таблицы адресов, а в si – номер конкретной процедуры
Основные команды
MOV – пересылка данных. Первый операнд замещается вторым
!для пересылки из памяти в память используют MOVS
!запрещено загружать сегментный регистр непосредственным значением (только через регистр) и пересылать из сегментного регистра в сегментный регистр (можно через стек)
XCHG – обмен данными между операндами
Пример:
mov ax, ff01h
mov si, 1000h
xchg ax,si
В результате выполнения команды xchg ax,si в AX будет 1000h, а в SI – ff01h
IN – ввод из порта
Вводит в AL или в AX из порта (внешнего устройства), адрес которого в DX. Если адрес порта меньше 255, тогда можно указывать непосредственное значение.
in al,60h ; ввод в AL из 60-го порта
mov dx,3d5h
in ax,dx
OUT – вывод в порт
Адрес порта должен находиться в DX, если адрес больше 255, иначе можно указывать непосредственное значение
out 61h, AL –
то, что находится в AL пишем по адресу 61, то есть по адресу
LES – загрузка указателя с использованием системного регистра ES
LEA – загрузка исполнительного адреса
lea si, mess аналогично mov,si,offset mess
LSS – загрузка указателя в сегментный регистр SS и указанный в команде регистр
