Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

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

Поиск

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

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

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

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

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

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

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

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

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

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


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

Model small

.stack 100h

.data

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

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

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

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

.code

mov ax, @data

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

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

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

mov ah, 0ah

mov dx, offset s1

int 21h

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

mov ah, 09h

mov dx, offset s3

int 21h

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

mov dl,’0’;в dl ascii-код 0

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

mov si, offset s0;в si адрес заданной строки-источника

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

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

mov di, offset s2;в di адрес введенной строки-приемника

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

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

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

repe scacb

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

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

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

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

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

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

loop z_str  

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

mov ah, 02h

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

mov ax,4c00h

int 21h

end

Массивы

 

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

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

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

mas db 1,2,3,4,5

mas dw 5 dup (0)

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

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

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

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

model    small

.stack 100h

.data

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

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

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

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

.code

main:

mov ax,@data

mov ds,ax

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

mov ah,0ah

mov dx, offset bufer

int 21h

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

xor si, si

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

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

m1: inc si          

cmp al, mas[si]

je m2

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

loop m1

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

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;вывод информационной строки

mov cx, 07h

mov ah, 01h

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

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

inc si

inc si

loop outcykl

pop cx

loop incykl

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

xor si,si

mov cx, 05h

s1t: push cx

mov cx, 06h

mov dx, mas[si]

maxi: add si, 2

cmp dx, mas[si]

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

mov dx, mas[si]

min1: loop maxi

;вывод максимального

mov ah, 02h

int 21h

pop cx

loop s1t

mov ax, 04c00h

int 21h

end main

Процедуры. Макрокоманды

Процедура, часто называемая подпрограммой, - это правильным образом оформленная совокупность команд, которая будучи однократно описана, при необходимости может быть вызвана в любом месте программы. Процедура представляет собой группу команд для решения конкретной подзадачи и обладает средствами получения управления из точки вызова задачи более высокого уровня и возврата управления в эту точку. В простейшем случае программа может состоять из одной процедуры.

Описание процедуры может размещается в любом месте программы, но таким образом чтобы на нее случайным образом не попало управление:

- в начале программы, до первой исполняемой команды;

- в конце, после команды возвращающей управление операционной системе;

- промежуточный вариант, тело процедуры располагается внутри другой процедуры или основной программы. В этом случае необходимо предусмотреть обход процедуры командой jmp;

- в другом модуле.

Синтаксис описания процедуры:

Имя_процедуры PROC              заголовок

Команды, директивы                тело процедуры

[ ret ]                                    возврат из процедуры

[имя_процедуры] ENDP            конец процедуры

Вызов процедуры осуществляется командой

CALL [модификатор] имя_процедуры

Команда call передает управление по адресу с символическим адресом имя_процедуры, с сохранением в стеке адреса возврата, команды следующей после команды call.

Возврат из процедуры осуществляется по команде

RET [число]

Команда ret считывает адрес возврата из стека и загружает его в регистры cs и ip/eip, возвращая таким образом управление команде, следующей за командой call. Число – необязательный параметр, обозначающий количество элементов, удаляемых из стека при возврате из процедуры. Размер элемента зависит от используемой модели сегментации 32 или 16 разрядной.

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

 

Пример.

Model small .stack 100h .data w db 25 dup (?) .code vvod proc mov ah, 0ah lea     dx, w int      21h ret vvod endp main: … Call schet Call   vvod … exit: mov ax,4c00h int 21h schet proc .. ret schet endp end main

 

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

Для работы с макрокомандой вначале необходимо задать ее шаблон-описание, так называемое макроопределение.

Имя_макрокоманды MACRO [список_формальных_аргументов]

<Тело макроопределения>

ENDM

Существует три варианта расположения макроопределений:

- в начале исходного текста программы до сегмента кода и данных с тем, чтобы не ухудшать читабельность программы. В данном случае макрокоманды будут актуальны только в пределах этой программы;

- в отдельном файле. Для того, чтобы использовать эти макроопределения в других программах, необходимо в начале исходного текста этих программ записать директиву

 include имя_файла

- в макробиблиотеке. Макробиблиотека создается в том случае, когда написанные макросы используются практически во всех программах. Подключается библиотека директивой include. Недостаток этого и предыдущего методов в том, что в исходный текст программы включаются абсолютно все макроопределения. Для исправления ситуации можно использовать директиву purge, в качестве операндов которой перечисляются макрокоманды, которые не должны включаться в текст программы.

Include macrobibl.inc;в исходный текст программы будут вставлены строки из macrobibl.inc

Purge outstr, exit;за исключением макроопределений outstr, exit

 

Активизация макроса осуществляется следующим образом:

Имя_макрокоманды список_ фактических_ аргументов

Model small Vivod macro rg Mov  dl, rg Mov  ah, 02h Int     21h endm .data .. .code .. vivod al .. Model small sravnenie         macro rg, met cmp rg, ‘a’ ja met add rg, 07h met: add rg, 30h endm .data .. .code .. sravnenie al, m1..

 

Функционально макроопределения похожи на процедуры. Сходство их в том, что и те, и другие достаточно один раз где-то описать, а затем вызывать их специальным образом. На этом их сходство заканчивается, и начинаются различия, которые в зависимости от целевой установки можно рассматривать и как достоинства и как недостатки:

- в отличие от процедуры, текст которой неизменен, макроопределение в процессе макрогенерации может меняться в соответствии с набором фактических параметров. При этом коррекции могут подвергаться как операнды команд, так и сами команды. Процедуры в этом отношении объекты менее гибки;

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


Пример 17. Найти максимальный элементы в каждой строке массива 5*7, с использованием процедур

model    small

.stack 100h

.data

mas dw 5 dup(7 dup(0))

max dw 0

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

.code

;процедура ввода строки

vvod _ str          proc

mov ah, 09h

lea dx, subj

int 21h

mov cx, 07h

mov ah, 01h

outcykl: int 21h

mov mas[si], ax

inc si

inc si

loop outcykl

ret

vvod _ str          endp

;процедура поиска максимального в строке

poick­_­maxi    proc

mov cx, 06h

mov dx, mas[si]

maxi: add si, 2

cmp dx, mas[si]

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

mov dx, mas[si]

min1: loop maxi

Ret

poick­_­maxi    endp

main proc

mov ax, @data

mov ds, ax

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

mov cx, 05h

incykl:   push cx

call vvod _ str    ;вызов процедуры по вводу строки

pop cx

loop incykl

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

xor si,si

mov cx, 05h

s1t: push cx

call poick ­_­ maxi    ;вызов процедуры поиска максимального элемента

mov ah, 02h          ;вывод максимального

int 21h

pop cx

loop s1t

mov ax, 04c00h

int 21h

end р main




Поделиться:


Последнее изменение этой страницы: 2021-01-08; просмотров: 126; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.223.195.30 (0.007 с.)