Смекни!
smekni.com

Программирование контроллера приоритетных прерываний (стр. 4 из 8)

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

xoral,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

Команды обработки строк

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

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

- Установить значение флага 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).

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

MODELsmall

.STACK256

.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 на значение, равное размеру элемента сравниваемых цепочек.

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

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

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

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

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

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

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

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

Загрузка элемента цепочки в аккумулятор

lods адрес_источника(LOaD String) — загрузить элемент из цепочки в регистр-аккумулятор al/ax/eax;
lodsb(LOaD String Byte) — загрузить байт из цепочки в регистр al;

lodsw (LOaDStringWord) — загрузить слово из цепочки в регистр ax;

lodsd (LOaDStringDoubleWord) — загрузить двойное слово из цепочки в регистр eax.

Эта операция-примитив позволяет извлечь элемент цепочки и поместить его в регистр-аккумулятор al, ax или eax. Эту операцию удобно использовать вместе с поиском (сканированием) с тем, чтобы, найдя нужный элемент, извлечь его (например, для изменения).

Перенос элемента из аккумулятора в цепочку

stos адрес_приемника(STOre String) - сохранить элемент из регистра-аккумулятора al/ax/eax в цепочке;

stosb (STOreStringByte) - сохранить байт из регистра al в цепочке;

stosw(STOreStringWord) - сохранить слово из регистра ax в цепочке;

stosd (STOreStringDoubleWord) - сохранить двойное слово из регистра eax в цепочке.

Эта операция-примитив позволяет произвести действие, обратное команде lods, то есть сохранить значение из регистра-аккумулятора в элементе цепочки. Эту операцию удобно использовать вместе с операцией поиска (сканирования) scans и загрузки lods, с тем, чтобы, найдя нужный элемент, извлечь его в регистр и записать на его место новое значение.


Пример 14. Подсчитайте количество несовпадающих элементов в заданной и введенной строках.

Model small

.stack 100h

.data

s0 db ‘Заданнаястрока$’

s1 db16 ;задаем количество символов во вводимой строке + знак Enters

s2 db?, 16 dup (?) ; ?- под количество введенных символов, массив под строку

s3 db 10,13, ‘Количество несовпадающих элементов - $' ;информац. строка

.code

movax, @data

movds, ax ;задаем адрес сегмента данных

moves, ax ;настраиваем адрес сегмента данных, где хранится строка приемник

;вводим сравниваемую строку

movah, 0ah

mov dx, offset s1

int 21h

;выводим информационную строку

movah, 09h

mov dx, offset s3

int 21h

;сравниваем строки, один элемент из заданной строки сравниваем со всеми ; элементами введенной строки

movdl,’0’ ;в dlascii-код 0

movcx, 16 ;в сх количество элементов в заданной строке

movsi, offsets0 ;в si адрес заданной строки-источника

z_str: pushcx ;сохраняем счетчик внешних циклов в стеке

lodsb ;загружаем элемент из заданной строки в аккумулятор, al

movdi, offsets2 ;в di адрес введенной строки-приемника

movcl, s2[di] ;в cl количество введенных элементов

xorch, ch ; обнуляем ch, т.к. в цикле счетчиком является сх

incdi ;на первый элемент строки-приемника

repescacb

;сканируем строку-приемник до тех пор пока элемент не = содержимому al,

;или пока не кончится строка

jzm1 ;zf=1, если в строке встретился элемент = содержимому al

incdl ; считаем количество не совпадающих элементов

m1: ;внутренний цикл по введенной строке закончился

popcx ;восстанавливаем содержимое сх

loopz_str

;после выхода из цикла в dl количество не совпадающих элементов

mov ah, 02h

int 21h ;выводим dl

mov ax,4c00h

int 21h

end

Массивы

Организация одномерных массивов

Все элементы массива располагаются в памяти последовательно

Описание элементов массива

masdb 1,2,3,4,5

masdw 5 dup (0)

Доступ к элементам массива

movax,mas[si] ; в si номер элемента в массиве

movmas[si], ax ; в di номер элемента в массиве

Пример 15. Найти в строке хотя бы один нулевой элемент

modelsmall

.stack 100h

.data

buferdw 25 ;формирую размер буфера для ввода строки

masdb 25 dup (' ') ;формирую буфер

subj1 db ‘в строке найден нулевой элемент', '$'

subj2 db ‘в строке не найден нулевой элемент', '$'

.code

main:

mov ax,@data

movds,ax

; ввод строки с клавиатуры

mov ah,0ah

mov dx, offset bufer

int 21h

;поиск нулевого элемента

xorsi, si

movcl, mas[si] ;загружаем в сх количество элементов в строке

moval, 030h ;в ax загружаем ASCII код нуля

m1: inc si

cmp al, mas[si]

je m2

;если в строке найдем нулевой элемент, то выходим из цикла на вывод subj1

loopm1

;нормальный выход из цикла означает что в строке нет нулевых элементов

lea dx, subj2

jmp m3

m2: lea dx,subj1

m3: mov ah, 09h

int 21h

mov ax,4c00h

int 21h

end main

Организация двумерных массивов

!Специальных средств для описания двумерных массивов в ассемблере нет!

Двумерный массив описывается также как и одномерный массив, отличие заключается в трактовке расположения элементов. Пусть последовательность элементов трактуется как двумерный массив, расположенный по строкам, тогда адрес элемента [i,j] вычисляется так

База+колич_элем_строке*размер_элем*I+j

Пример 16. Найти максимальный элементы в каждой строке массива 5*7

model small

.stack 100h

.data

mas dw 5 dup( 7 dup(0))

max dw 0

subj db ‘введитестроку',13,10,'$'

.code

main:

mov ax, @data

mov ds, ax

;заполнение массива

xor si, si

mov cx, 05h

incykl: push cx

mov ah, 09h

lea dx, subj

int 21h ;вывод информационной строки

movcx, 07h

mov ah, 01h

outcykl: int 21h ;ввод элементов массива

movmas[si], ax ;размещение элементов на месте

inc si

inc si

loop outcykl

popcx

loopincykl

;поиск максимального/ минимального в строках

xor si,si

mov cx, 05h

s1t: push cx

mov cx, 06h

mov dx, mas[si]

maxi: add si, 2

cmpdx, mas[si]

ja min1 ;если меньше то переходим