- •Теоретичні відомості
- •1. Структура простої програми мовою асемблера. Формат кодування програми.
- •2. Основні директиви : segment , end, ends, proc, endp, assume.
- •3. Основні вимоги при створенні програми. Приклади простих програм мовою асемблера.
- •4. Трансляція програми. Опції компіляції та загальна характеристика.
- •6. Застосування програми налагодження для пошуку помилок.
- •Розв’язування задач за тематикою заняття
- •Завдання для самостійної роботи
- •Теоретичні відомості
- •1. Директиви визначення даних.
- •2. Директива повторення dup.
- •3. Сталі.
- •5. Представлення в пам’яті цілих чисел.
- •6. Команда пересилки даних mov.
- •7. Команди двійкового додавання та віднімання.
- •Команда зміни знаку операнда neg
- •8. Обчислення цілих арифметичних виразів.
- •Розв’язування задач за тематикою заняття
- •Завдання для самостійної роботи.
- •Теоретичні відомості
- •1. Команда безумовного переходу jmp. Типи адресів переходу short,near та far.
- •2. Команди організації циклів ( loop,loopn,loopnz). Команда loop. Керування циклом за ecx/cx.
- •Керування циклом за ecx/cx із врахуванням ознаки zf
- •3. Команди умовних переходів.
- •5. Команда lea
- •Команда роботи зі стеком push та pop
- •Розв’язування задач за тематикою заняття
- •Завдання для самостійної роботи.
- •Розв’язування задач за тематикою заняття
- •Завдання для самостійної роботи.
- •Логічні операції та операції зсувів.
- •2. Команди логічних операцій (and, test, or, xor, not).
- •3. Команди зсувів та циклічних зсувів.
- •Команди зсувів (sal, sar, shl,shr)
- •Команда зсуву логічного операнда вправо – shr
- •3.2 Команди циклічних зсувів (rol, ror ,rcl, rcr). Циклічний зсув операнда вліво - rol
- •Циклічний зсув операнда вправо ror
- •Циклічний зсув операнда вліво через ознаку переносу - rcl
- •Циклічний зсув операнда вправо через ознаку переносу – rcr
- •Бітові маски.
- •Розв’язування задач за тематикою заняття
- •Завдання для самостійної роботи
- •1. Множення цілих чисел
- •2. Ділення цілих чисел
- •3. Перетворення в регістрах
- •Алгоритм введення–виведення цілих чисел
- •Виведення цілих чисел.
- •Введення цілих чисел.
- •Розв’язування задач за тематикою заняття
- •Завдання для самостійної роботи.
- •Теоретичні відомості
- •Особливості команд обробки рядків.
- •Ознака df. Команди зміни ознаки ( cld, std ).
- •Префікси повторення( rep, repe, repz, repne, repze ).
- •Команди обробки символьних рядків
Ознака df. Команди зміни ознаки ( cld, std ).
Ознака DF регістра ознак вказує напрямок обробки ланцюжків даних. Для того щоб явно в програмі вказати напрямок обробки ланцюжка даних використовується команди CLD та STD.
Команда встановлення ознаки напрямку STD.
Схема команди : STD
Призначення: встановити ознаку DF, тобто DF=1.
Команда скидання в нуль ознаки напрямку CLD.
Схема команди : CLD
Призначення: скинути ознаку DF, тобто DF=0.
Префікси повторення( 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.
Префікси повторення мають сенс тільки при використанні ланцюжкових операцій.
Команди обробки символьних рядків
Команди пересилання рядків байтів/слів/подвійних слів 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
Завдання для самостійної роботи.
Написати програму, яка копіює 1024 байтів однієї області у іншу.
Циклічно зсунути на сім байтів вліво символьний pядок.
Задано масив беззнакових цілих чисел розмірності N. Поміняти у масиві входження числа - 1000 на 7000.
Задано рядок s1 де заходиться слово та рядок s2 з текстом. Написати підпрограму, перевіряє вхоження слова в рядку s1 у s2.
Написати програму кодування символьного рядка. Для кодування кожний байт циклічно зсунути на один біт вправо.
Список літе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.