Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
asm.doc
Скачиваний:
6
Добавлен:
09.11.2019
Размер:
913.41 Кб
Скачать
  1. Ознака df. Команди зміни ознаки ( cld, std ).

Ознака DF регістра ознак вказує напрямок обробки ланцюжків даних. Для того щоб явно в програмі вказати напрямок обробки ланцюжка даних використовується команди CLD та STD.

Команда встановлення ознаки напрямку STD.

Схема команди : STD

Призначення: встановити ознаку DF, тобто DF=1.

Команда скидання в нуль ознаки напрямку CLD.

Схема команди : CLD

Призначення: скинути ознаку DF, тобто DF=0.

  1. Префікси повторення( rep, repe, repz, repne, repze ).

Команди(префікси) повторення ланцюжкових операцій

Схема команд : REP

REPE

REPZ

REPNE

REPNZ

Призначення: вказівка умовного і безумовного повторення наступної за даною командою ланцюжкової операції.

Алгоритм роботи REP:

Крок 1) аналізуємо вміст CX – якщо CX<>0, то виконати ланцюжкову команду, яка заходиться за даним префіксом, в противному випадку (якщо CX=0) передати керування команді, яка знаходиться за даною ланцюжковою командою (вийти з циклу REP);

Крок 2) зменшити значення CX=CX–1 і повернутися до кроку 1.

REP використовується перед наступними ланцюжковими командами і їхніми короткими еквівалентами: MOVS, STOS, INS та OUTS.

Алгоритм роботи REPE та REPZ :

Крок 1) аналізуємо вміст регістра CX та ознаки ZF– якщо CX<>0 і ZF=1, то виконати ланцюжкову команду, яка заходиться за даним префіксом, в противному випадку (якщо CX=0 або ZF=0 ) передати керування команді, яка знаходиться за даною ланцюжковою командою (вийти з циклу REPE);

Крок 2) зменшити значення CX=CX–1 і повернутися до кроку 1.

REPE та REPZ використовується перед наступними ланцюжковими командами і їхніми короткими еквівалентами: CMPS та SCAS.

Алгоритм роботи REPNE та REPNZ :

Крок 1) аналізуємо вміст регістра CX та ознаки ZF– якщо CX<>0 і ZF=0, то виконати ланцюжкову команду, яка заходиться за даним префіксом, в противному випадку (якщо CX=0 або ZF=1 ) передати керування команді, яка знаходиться за даною ланцюжковою командою (вийти з циклу REPNE);

Крок 2) зменшити значення CX=CX–1 і повернутися до кроку 1.

REPNE та REPNZ використовується перед наступними ланцюжковими командами і їхніми короткими еквівалентами: CMPS та SCAS.

Префікси повторення мають сенс тільки при використанні ланцюжкових операцій.

  1. Команди обробки символьних рядків

Команди пересилання рядків байтів/слів/подвійних слів MOVS

Схема команди : MOVS приймач, джерело

MOVSB

MOVSW

MOVSD

Призначення: пересилання елементів двох послідовностей (ланцюжків) у пам'яті.

Алгоритм роботи: виконується копіювання байта, слова або подвійного слова із операнда джерела в операнд приймач, при цьому адреси елементів попередньо повинні бути завантажені; у залежності від стану ознаки DF змінюється значення регістрів ESI/SI і EDI/DI.

Стан прапорів після виконання команди: виконання команди не впливає на прапори

Застосування: Команди пересилають елемент з однієї комірки пам'яті в іншу. Розміри елементів, які пересилаються, залежать від застосовуваної команди. Команда MOVS може працювати з елементами розміром у байт, слово, подвійне слово. У якості операндів у команді вказуються ідентифікатори послідовностей цих елементів у пам'яті. Реально ці ідентифікатори використовуються лише для одержання типів елементів послідовностей, а їхні адреси повинні бути попередньо завантажені в зазначені вище пари регістрів. Транслятор, обробивши команду MOVS і з'ясувавши тип операндів, генерує одну з машинних команд MOVSB, MOVSW або MOVSD.

Команди порівняння рядків байтів/слів/подвійних слів CMPS

Схема команди : CMPS приймач, джерело

CMPSB

CMPSW

CMPSD

Призначення: порівняння двох послідовностей (ланцюжків) елементів у пам'яті.

Алгоритм роботи: виконується віднімання елементів (джерело - приймач), при цьому значення елементів не змінюється, змінюється значення регістрів ESI/SI і EDI/DI у залежності від стану ознаки DF, та в залежності від результату віднімання встановлюються ознаки:

    • якщо чергові елементи ланцюжків не рівні, то CF=1, ZF=0;

    • якщо чергові елементи або ланцюжків ланцюжка в цілому рівні, то CF=0, ZF=1.

Стан ознак після виконання команди: OF, CF, AF, SF, ZF та PF – залежить від результату роботи команди.

Для того щоб ці команди можна було використовувати для порівняння послідовності елементів необхідно використовувати один із префіксів REPE або REPNE. Ці префікси не тільки змушують циклічно виконуватися команду, поки ECX/CX<>0, але і відслідковують стан ознаки ZF.

Команди сканування рядка байтів/слів/подвійних слів SCAS

Схема команди : SCAS приймач

SCASB

SCASW

SCASD

Призначення: пошук значення в послідовності (ланцюжку) елементів у пам'яті.

Алгоритм роботи: виконується віднімання елементів (приймач – EAX/AX/AL), при цьому значення елементів не змінюється, змінюється значення регістра EDI/DI (приймач – визначається парою ES:EDI/DI); за результатом віднімання встановлюються ознаки.

Стан ознак після виконання команди: OF, CF, AF, SF, ZF та PF – залежить від результату роботи команди.

Команди сканування порівнюють значення в регістрі EAX/AX/AL з коміркою пам'яті, яка локалізується парою регістрів ES:EDI/DI.

Для того щоб ці команди можна було використовувати для порівняння послідовності елементів необхідно використовувати один із префіксів REPE або REPNE. Ці префікси не тільки змушують циклічно виконуватися команду, поки ECX/CX<>0, але і відслідковують стан ознаки ZF.

Команди завантаження рядка байтів/слів/подвійних слів LODS

Схема команди : LODS джерело

LODSB

LODSW

LODSD

Призначення: завантаження елемента з послідовності (ланцюжка) у регістр-акумулятор AL/AX/EAX.

Алгоритм роботи: завантажується елемент із комірки пам'яті, яка адресується парою DS:ESI/SI (DS за замовчуванням, допускається заміна сегмента), у регістр AL/AX/EAX, змінюється значення регістра ESI/SI на величину, рівну довжині елемента ланцюжка.

Стан ознак після виконання команди: виконання команди не впливає на ознаки.

Застосування: Цю команду використовують у деякому циклі для перегляду деякого ланцюжка з елементами фіксованого розміру.

Команда збереження рядка байтів/слів/подвійних слів STOS

Схема команди : STOS приймач

STOSB

STOSW

STOSD

Призначення: збереження елемента з регістра-акумулятора AL/AX/EAX у послідовності (ланцюжку).

Алгоритм роботи: записується елемент із регістра AL/AX/EAX у комірку пам'яті, яка адресується парою ES:EDI/DI, змінюється значення регістра EDI/DI на величину, рівну довжині елемента ланцюжка.

Стан ознак після виконання команди: виконання команди не впливає на ознаки.

Застосування: Цю команду використовують у деякому циклі для зберігання вмісту акумулятора AL/AX/EAX у деякому ланцюжку в пам’яті.

Команди LODS та STOS можуть використовуватися в парі для перетворення ланцюжка.

Приклади розв’язання задач на обробку ланцюжків.

Приклад 1 (Використання команди MOVS). Написати програму, яка копіює 1024 слів однієї області у іншу.

DosSeg

.Model Small

.Stack 100h

.Data

num = 1024

Sector1 dd $+4 $ - оператор повертає зміщення в сегменті.

Buf1 dw num dup('**'),'$'

Sector2 dd $+4

Buf2 dw num dup('++’),'$'

.Code

.StartUp

Call CopySector ;Виклик процедури копіювання секторів

mov ah,09h ;Вивід на екран слова OK

mov dx,offset Buf2

int 21h

.Exit 1

CopySector proc

cld ; Встановити напрямок обробки рядка “вперед” (df=0).

push DS ; Зберегти вміст сегментних регістрів DS і ES.

push ES

les DI,Sector2; Завантаження адреси в сегментні та індексні регістри

lds SI,Sector1; початків областей ( ES:DI - Sector2, DS:SI - Sector1).

mov CX,1024;Кількість елементів, що копіюємо з Sector1 у Sector2.

rep movsw ; Копіювання елементів.

pop ES ; Відновлення вмісту сегментних регістрів.

pop DS

ret

CopySector endp

End

Приклад 2 (Використання команди MOVS). Циклічно зсунути на вісім байтів вправо символьний рядок.

DosSeg

.Model Small

.Stack 100h

.Data

Sb db ' Цей рядок буде зсунутий на вісім позицій вправо. $'

NumByte dw $ - Sb

Temp db 8 dup('q')

.Code

.StartUp

mov AH,09h ;Вивід на екран стрічки Sb

mov DX,offset Sb

int 21h

Call ShiftByte ;Виклик процедури ShiftByte

mov AH,09h

mov DX,offset Sb

int 21h

.Exit

.Code

ShiftByte Proc

;Процедура зсуву:

std ; Встановити напрямок обробки рядка “назад” (df=1).

lea SI, NumByte-2 ; Адреса останнього символу рядка.

push DS ; Ініціалізація регістра ES.

pop ES

push SI ; Збереження індексування останнього символу.

lea DI,Temp+7 ; Зберігання 8 останніх символів рядка

mov CX,8 ; у тимчасовому(допоміжному) масиві.

rep movsb

pop DI ; Відновлення індексу останнього символу.

mov CX, NumByte ; Завантажуємо у регістр кількість символів,

sub CX,9 ; які будемо зсувати.

rep movsb ; Зсув символів на 8 байтів.

lea SI,Temp+7 ; Переміщення символів, які тимчасово

; зберігалися

mov CX,8 ; у допоміжному масиві на їх нові позиції.

rep movsb

ret

ShiftByte Endp

End

Приклад 3 (Використання команди CMPS). Написати підпрограму , яка порівнює два символьні рядки s1 и s2 (що задаються у сегменті даних). Результат порівняння записує у регістр AX. Результатом порівняння буде номер більшого символьного рядка ( тобто 1 або 2 ), або значення 0, якщо вони рівні. Рядок вважається більшим, якщо його перша буква, що не співпала з буквою іншого рядка, має більше значення ASCII коду.

; Подається тільки фрагменти сегменту коду та даних, які стосуються розв’язання задачі.

.Data

;..................

StComp1 db 'First string','$'

SizeComp1 = $ - StComp1-1

StComp2 db 'First znot string','$'

SizeComp2 = $ - StComp2-1

.Code

;...............

СmpString Proc

мov CX,SizeComp1 ; Довжина першого рядка.

сmp CX,SizeComp2 ; Порівняння довжин рядків.

jl mst ; В регістр CX меншу довжину.

mov CX,SizeComp2 ; Довжина другого рядка.

mst: cld ; Встановити напрямок обробки рядка “вперед” (df=0).

lea SI,StComp1 ; Індексування рядка StComp1 регістрами DS:SI.

push DS ; Ініціалізація регістра ES.

pop ES

lea DI, StComp2 ; Індексування рядка StComp2 регістрами ES:DI.

repe cmpsb ; Порівняння символів, поки вони рівні.

;Аналіз виходу з циклу порівняння. Зробимо гіпотезу ,що рядки рівні.

mov AX,0 ; Тобто AX=0.

je mquit ; Вихід, якщо вони рівні.

mov AX,1 ; Нехай перший рядок більший ( AX=1).

ja mquit ; Вихід, якщо перший рядок більший.

mov AX,2 ; Другий рядок більший.

mquit: ret

СmpString EndP

;......

End

Приклад (Використання команди SCAS). Задано масив знакових цілих чисел розмірності N. Поміняти у масиві входження числа - 24495 на 7000.

Stacks Segment para 'Stack'

dw 100 dup(?)

Stacks Ends

Data Segment para 'Data'

NumVec = 10

Vec dw 0,-24495,-3,-24496,-24495,24495,0,0,-24495,9

Data Ends

Code Segment para 'code'

Assume cs:Code,ds:Data,es:Data,ss:Stacks

include in&out.asm

ScanNum Proc near

;Процедура заміни -24495 на 7000

cld ; Встановити напрямок обробки рядка “вперед” (df=0).

push ds ; Ініціалізація регістра ES.

pop es

lea di,Vec ; Адреса першого елемента вектора (ES:DI).

mov cx,NumVec ;Розмів масиву.

mov ax,-24495 ;Шукане число.

m: repne scasw ; Сканувати масив, поки не -4495 або кінець вектора.

jne m1 ; Якщо поточне число не -24495 ,то вихід.

mov word ptr [di-2],7000 ; Поміняти -24495 на 7000.

cmp cx,0 ;

jcxz m1

jmp m ; Продовжити пошук.

m1: nop

ret

ScanNum Endp

Main Proc far

push ds

sub ax,ax

push ax

mov ax,Data

mov ds,ax

call ScanNum ;Виклик процедури

ret

Endp

Code Ends

End Main

Приклад 5(Використання команд LODS та STOS). Написати програму кодування символьного рядка. Для кодування кожний байт циклічно зсунути на один біт вправо.

Stacks Segment para 'Stack'

dw 100 dup(?)

Stacks Ends

Data Segment para 'Data'

NCb1 equ 90

sCb label byte

nm ax db NCB1

ncb db ?

Cb db NCb1 Dup (?),'$'

Data Ends

Code Segment para 'code'

Assume cs:Code,ds:Data,es:Data,ss:Stacks

include in&out.asm

RCodeByte Proc

cld ; Встановити напpямок обpобки рядка “вперед” (df=0).

push ds ; Ініціалізація регістра ES.

pop es

lea si,Cb ;Завантажити в SI та DI

lea di,Cb ; адресу Cb

mov cl,ncb ; кількість байтів

xor ch,ch

m15: lodsb ;

ror al,1 ;

stosb

loop m15

ret

RCodeByte Endp

Main Proc far

;Основна процедура програми

push ds

sub ax,ax

push ax

mov ax,Data

mov ds,ax

lea dx,sCb ;Завантажити в DX адресу sCb

call inpstr ;Читання sCb

call RCodeByte ;Виклик процедури RcodeByte

call newline ;Перехід на новий рядок

lea dx,Cb ;Вивід на

call outstr ;екран стрічки Cb

ret

Endp

Code Ends

End Main

Завдання для самостійної роботи.

  1. Написати програму, яка копіює 1024 байтів однієї області у іншу.

  2. Циклічно зсунути на сім байтів вліво символьний pядок.

  3. Задано масив беззнакових цілих чисел розмірності N. Поміняти у масиві входження числа - 1000 на 7000.

  4. Задано рядок s1 де заходиться слово та рядок s2 з текстом. Написати підпрограму, перевіряє вхоження слова в рядку s1 у s2.

  5. Написати програму кодування символьного рядка. Для кодування кожний байт циклічно зсунути на один біт вправо.

Список літеpатуpи

1.Абель П. Язык Ассемблера для IBM PC и программирования / Пер. с англ. Ю.В.Сальникова.-М:Высш. шк., 1992.-447с.:ил.

2. Исида Х. Программирование для микрокомпьютеров: И85 Пер. с яп.-М: Мир, 1988 .-224 с., ил.

3. Использование Turbo Assembler при разработке программ / Сост. А.А. Чекатов. – Киев: “Диалектика”, 1995.-288 с.

4. Морс С.П., Алберт Д.Д. Архитектура микропроцессора 80286: Пер. с англ.- М.: Радио и связь, 1990.-304 с.: ил.

5. Григорьев В.Л. Микропроцессор і486. Архитектура и программирование ( в 4-х книгах). Книга 1. Программная архитектура. –М., ГРАНАЛ, 1993.- с. 346, ил. 87

6. Григорьев В.Л. Микропроцессор і486. Архитектура и програмирование ( в 4-х книгах). Книга 2. Аппаратная архитектура. Книга 3. Устройство с плавающей точкой. Книга 4. Спправочник по системе команд.-М., ГРАНАЛ, 1993.- с. 382, ил. 54.

72

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]