Смекни!
smekni.com

Программная модель процессоров семейства X86 (стр. 5 из 9)

m1:

pushcx

movcx,n1; в сх заносим количество итераций внутреннего цикла

m2:

тело внутреннего цикла

loopm2

popcx

loopm1

Пример программы: Напишите программу подсчета у=1+2+3+…+n, n не более 10000.

model small

.stack 100h

.data

yb dd ?

ym dw ?

s1 db 'введите n',10,13,'$'

.code

start:

mov ax,@data

mov ds,ax

mov dx, offset s1

mov ah,09h

int 21h


mov cx,3

m: shl bx,4

movah,01h

int 21h вводим n в регистр bx

sub ax,130h

add bx,ax

loop m

mov cx,bx

xor dx,dx

xor al,al

m1: adddx,cx считаем у

jnc m2

mov al,1

m2: loop m1

cmp al,1

je m3

mov ym,dx

m3: mov yb,edx

mov ax,4c00h

int 21h

end start

Цепочечные команды

(Команды обработки строк символов)

Цепочка – это последовательность элементов, размер которых может быть байт, слово, двойное слово. Содержимое этих элементов может быть любое – символы, числа.

В системе команд микропроцессора имеется семь операций-примитивов обработки цепочек.

Каждая из них реализуется в микропроцессоре тремя командами, в свою очередь, каждая из этих команд работает с соответствующим размером элемента — байтом, словом или двойным словом.

Вместе с цепочечными командами обычно применяют префиксы повторений, которые ставятся перед командой в поле [метки]. Цепочечная команда без префикса выполняется один раз. С префиксом цепочечные команды выполняются циклично.

rep (REPeat) - команда выполняется, пока содержимое в ecx/cx не станет равным 0. При этом цепочечная команда, перед которой стоит префикс, автоматически уменьшает содержимое ecx/cx на единицу. Та же команда, но без префикса, этого не делает.

repe или repz (REPeatwhileEqualorZero) - команда выполняется до тех пор, пока содержимое ecx/cx не равно нулю или флаг zf равен 1. Как только одно из этих условий нарушается, управление передается следующей команде программы

repne или repnz(REPeatwhileNotEqualorZero) - команда циклически выполняется до тех пор, пока содержимое ecx/cx не равно нулю или флаг zf равен нулю. При невыполнении одного из этих условий работа команды прекращается.

Формирования физического адреса операндов адрес_источника и адрес_приемника происходит следующим образом:

адрес_источника — пара ds:esi/si;

адрес_приемника — пара es:edi/di

Важный момент, касающийся всех цепочечных команд, — это направление обработки цепочки. Есть две возможности:

- от начала цепочки к ее концу, то есть в направлении возрастания адресов;

- от конца цепочки к началу, то есть в направлении убывания адресов.

Цепочечные команды сами выполняют модификацию регистров, адресующих операнды, обеспечивая тем самым автоматическое продвижение по цепочке. Количество байт, на которые эта модификация осуществляется, определяется кодом команды. А вот знак этой модификации определяется значением флага направления df (Direction Flag) в регистре eflags/flags. Состоянием флага df можно управлять с помощью двух команд, не имеющих операндов:

cld (Clear Direction Flag) — очистить флаг направления df = 0, значение индексных регистров esi/si и edi/di будет автоматически увеличиваться (операция инкремента) цепочечными командами, то есть обработка будет осуществляться в направлении возрастания адресов;

std (Set Direction Flag) — установить флаг направления df = 1, то значение индексных регистров esi/si и edi/di будет автоматически уменьшаться (операция декремента) цепочечными командами, то есть обработка будет идти в направлении убывания адресов.

Типовой набор действий для выполнения любой цепочечной команды:

- Установить значение флага df в зависимости от того, в каком направлении будут обрабатываться элементы цепочки — в направлении возрастания или убывания адресов.

- Загрузить указатели на адреса цепочек в памяти в пары регистров ds:(e)si и es: (e)di.

- Загрузить в регистр ecx/cx количество элементов, подлежащих обработке.

- Выдать цепочечную команду с префиксом повторений.

Пересылка цепочек

movs адрес_прием, адрес_источника (MOVeString)- переслать цепочку;

movsbMOVe String Byte) — переслатьцепочкубайт;

movsw (MOVe String Word) — переслатьцепочкуслов;

movsd (MOVe String Double word) — переслатьцепочкудвойныхслов.

Команда копирует байт, слово или двойное слово из цепочки источника, в цепочку приемника. Размер пересылаемых элементов ассемблер определяет, исходя из атрибутов идентификаторов. К примеру, если эти идентификаторы были определены директивой db, то пересылаться будут байты, если идентификаторы были определены с помощью директивы dd, то пересылке подлежат двойные слова.

Для цепочечных команд с операндами типа movs адрес_приемника,адрес_источника, не существует машинного аналога. При трансляции в зависимости от типа операндов транслятор преобразует ее в одну из трех машинных команд: movsb, movsw или movsd.

Сама по себе команда movs пересылает только один элемент, исходя из его типа, и модифицирует значения регистров esi/si и edi/di. Если перед командой написать префикс rep, то одной командой можно переслать до 64 Кбайт данных. Число пересылаемых элементов должно быть загружено в счетчик — регистр cx (use16) или ecx (use32).

Примерпроги. Пересылкастроккомандой movs

MODEL small

STACK 256

.data

source db 'Тестируемаястрока','$' ;строка-источник

dest db 19 DUP (' ') ;строка-приёмник

.code

main:

mov ax,@data ;загрузка сегментных регистров

mov ds,ax ;настройка регистров DS и ES на адрес сегмента данных

mov es,ax

cld ;сброс флага DF — обработка строки от начала к концу

lea si,source ;загрузка в si смещения строки-источника

lea di,dest ;загрузка в DS смещения строки-приёмника

mov cx,20 ;для префикса rep — счетчик повторений (длина строки)

rep movs dest,source ;пересылкастроки

lea dx,dest

mov ah,09h ;вывод на экран строки-приёмника

int 21h

mov ax,4c00h

int 21h

endmain

Операция сравнения цепочек

cmps адрес_приемника,адрес_источника(CoMPare String) — сравнить строки;

cmpsb (CoMPare String Byte) — сравнитьстрокубайт;

cmpsw (CoMPare String Word) — сравнитьстрокуслов;

cmpsd (CoMPare String Double word) — сравнитьстрокудвойныхслов.

Алгоритм работы команды cmps заключается в последовательном выполнении вычитания (элемент цепочки-источника — элемент цепочки-получателя) над очередными элементами обеих цепочек. Принцип выполнения вычитания командой cmps аналогичен команде сравнения cmp. Она, так же, как и cmp, производит вычитание элементов, не записывая при этом результата, и устанавливает флаги zf, sf и of.

После выполнения вычитания очередных элементов цепочек командой cmps, индексные регистры esi/si и edi/di автоматически изменяются в соответствии со значением флага df на значение, равное размеру элемента сравниваемых цепочек.

Чтобы заставить команду cmps выполняться несколько раз, то есть производить последовательное сравнение элементов цепочек, необходимо перед командой cmps определить префикс повторения. С командой cmps можно использовать префикс повторения repe/repz или repne/repnz:

- repe или repz — если необходимо организовать сравнение до тех пор, пока не будет выполнено одно из двух условий: достигнут конец цепочки (содержимое ecx/cx равно нулю) или в цепочках встретились разные элементы (флаг zf стал равен нулю);

- repne или repnz — если нужно проводить сравнение до тех пор, пока: не будет достигнут конец цепочки (содержимое ecx/cx равно нулю) или в цепочках встретились одинаковые элементы (флаг zf стал равен единице).

Пример программы Сравнение двух строк командой cmps

MODEL small

STACK 256

.data

sov db 0ah,0dh,'Строкисовпадают.','$'

nesov db 0ah,0dh,'Строки не совпадают','$'

s1 db '0123456789',0ah,0dh,'$';исследуемые строки

s2 db 10

s3 db 11 dup (0)

.code

main:

mov ax,@data ;загрузка сегментных регистров

mov ds,ax

mov es,ax ;настройка ES на DS

;вводимстроку

mov ah, 0аh

mov dx, offset s2

int 21h

;поиск совпадающих элементов, сброс флага DF - сравнение в направлении возрастания адресов

cld

lea si,s1 ;загрузкав si смещения string1

leadi,s3 ;загрузка в di смещения string2

mov cx,10 ;длина строки для префикса repe

repecmpsb ;сравнение строк (пока сравниваемые элементы строк равны)

;выход при обнаружении не совпавшего элемента

jcxz equal ;cx=0, то есть строки совпадают

lea dx, nesov

jmp exit ;выход

equal: lea dx, sov

exit: mov ah,09h

int 21h ;вывод сообщения

movax,4c00h

int21h

end main ;конец программы

Операция сканирования цепочек

scas адрес_приемника (SCAning String) — сканировать цепочку;

scasb (SCAningStringByte) — сканировать цепочку байт;

scasw (SCAning String Word) — сканироватьцепочкуслов;

scasd (SCAning String Double Word) — сканироватьцепочкудвойныхслов

Эти команды осуществляют поиск искомого значения, которое находится в регистре al/ax/eax. Принцип поиска тот же, что и в команде сравнения cmps, то есть последовательное выполнение вычитания

(содержимое регистра_аккумулятора – содержимое очередного_элемента_цепочки).

В зависимости от результатов вычитания производится установка флагов, при этом сами операнды не изменяются.

Так же, как и в случае команды cmps, с командой scas удобно использовать префиксы repe/repz или repne/repnz:

- repe или repz — если нужно организовать поиск до тех пор, пока не будет выполнено одно из двух условий: достигнут конец цепочки (содержимое ecx/cx равно 0) или в цепочке встретился элемент, отличный от элемента в регистре al/ax/eax;

- repne или repnz — если нужно организовать поиск до тех пор, пока не будет выполнено одно из двух условий достигнут конец цепочки (содержимое ecx/cx равно 0)или в цепочке встретился элемент, совпадающий с элементом в регистре al/ax/eax.

Пример проги. найти количество * в строке

MODEL small

STACK 256

.data

s1 db 20

s2 db 21 dup ?

s3 db 'количество * в строке',0ah,0dh,'$'