Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Практикум_СП

.pdf
Скачиваний:
39
Добавлен:
15.02.2015
Размер:
1.01 Mб
Скачать

;Приклади безумовних переходів.

;Модулі mod1 і mod2 асемблюються окремо.

NAMEmod1 Dseg SEGMENT

Addr_JN DW Go_Nxt

 

 

;адреса переходу Offset Addr.JF DD Start_0 адреса

;переходу Seg Offset

 

 

 

Tabl_JN DW Fadd, Fsub, Fmul, Fdiv

;таб.адр. переходу Offset

Tabl_JF DD Dadd.Dsub.Dmul.Ddiv ;те ж, але у вигляді Seg:Qffset

SwitchDW ?

 

 

;перемикач: 0, 1, 2 або 3

Dseg

ENDS

 

 

 

Cseg1 SEGMENT 'CODE'

 

 

 

 

EXTRN Begin:FAR

 

 

 

Start

PROC FAR

 

 

 

 

PUSH DS

 

;підготуватися

 

SUB AX, AX

 

;до повернення

 

PUSH AX

 

;у DOS

; Приклади внутрішньосегментних переходів

Start_0:

 

 

 

JMP SHORT Cont

;короткий перехід в сегменті

Go_Nxt:

 

 

 

MOV SI, Switch

 

 

 

 

SHL SI,1

 

 

;підготувати покажчик в таблиці

 

JMP Tabl_JN[Sl]

 

 

;непрямий перехід в сегменті

 

...

 

 

 

 

JMP Addr_JN

 

 

;непрямий перехід на Go_Nxt

 

...

 

 

 

 

JMP Tabl_JN + 4

 

 

;непрямий перехід на Fmul

 

...

 

 

 

 

MOV BX,Tabl_JN[Sl]

 

;ВК = адреса з таблиці

 

JMP ВХ

 

 

;непрямий перехід за адресою у ВХ

 

...

 

 

 

 

LEA BX,Tabl_JN

 

 

;ВК = база таблиці

 

JMP NEAR PTR [ВХ]

 

;непрямий перехід на Fadd

 

...

 

 

 

 

JMP NEAR PTR [BX][SI]

 

;непрямий перехід за адресою з таблиці Tabl_JN,

;який визначається перемикачем в S1

 

 

JMP Go_Nxt

 

 

;прямий перехід в сегменті типу NEAR

; Приклади міжсегментних переходів

 

 

JMP Begin

 

 

;прямий міжсегментний по зовнішній мітці

 

...

 

 

 

 

JMP DSUB

 

 

;прямий міжсегментний по мітці типу F

 

...

 

 

 

 

JMP Tabl_JF + 8

 

;непрямий міжсегментний на Dmul

 

...

 

 

 

 

MOV SI,Switch

 

;перемикач адреси дальнього переходу SHL SI.1

 

SHL SI.1

 

;4*S1 = 0, 4, 8 або 12

 

JMP Tabl_JF[SI]

 

;непрямий міжсегментний по таблиці

 

...

 

 

 

 

LEA BX,Tabl_JF

 

;ВХ = база таблиці

51

 

JMP

FAR PTR [BX]

;непрямий міжсегментний на Da

 

...

 

 

 

 

JMP

FAR PTR [ВX][SI]

;непрямий міжсегментний за адресою з таблиці Tabl_JF,

;який визначається перемикачем

 

 

...

 

 

 

 

RET

 

 

;повернення в DOS

Cseg1 ENDS

 

 

 

Cseg2 SEGMENT 'CODE' NAME mod2

Cseg3 SEGMENT 'CODE'

 

Dadd

LABEL FARPUBLIC Begin

 

Fadd: .

.

 

 

Begin:

.

 

 

.

 

 

 

 

Dsub LABEL FAR .

 

Fsub . Cseg3 ENDS

 

 

 

.

END

 

;

.

 

 

 

 

 

 

 

Dmul

LABEL

FAR

 

Fmul: .

 

 

 

 

.

 

 

 

;

.

 

 

 

 

 

 

 

Ddiv

LABEL

FAR

 

Fdiv: .

 

 

 

 

.

 

 

 

 

.

 

 

 

 

JMP Addr_JF

;непрямий міжсегментний за адр. у пам'яті

Cseg2 ENDS

 

 

 

;

END

Start

 

 

 

 

 

Приклад програми, яка наочно демонструє виконання переходів. Наберіть текст у будь-якому текстовому редакторі, скомпілюйте і скомпонуйте файл у виконуваний та запустіть на виконання.

IDEAL

 

MODEL small

 

Stack 256

 

DATASEG

;Сегмент даних

Promt DB'Vze den? (Yes/No - y/n)$'

GoodMorning DB 13,10,'Dobroe utro!',13,10,'$'

GoodAfternoon DB 13,10,'Dobryi den!',13,10,'$'

TiZavtrakal DB 13,10,'Ti uje zavtrakal? (Yes/No - y/n)$'

TiObedal DB 13,10,'Ti uje obedal? (Yes/No - y/n)$'

Zavtrakal DB 13,10,'Horosho, chto pozavtrakal =)$'

Obedal DB 13,10,'Horosho, chto poobedal =)$'

NeZavtrakal DB 13,10,'Priyatnogo appetita k zavtraku!!!$'

NeObedal DB 13,10,'Priyatnogp appetita k obedu!!!$'

CODESEG ;Сегмент коду

52

START:

 

mov ax,@data

 

mov ds,ax

 

mov dx,OFFSET Promt

 

mov ah,9

 

int 21h

 

mov ah,1

 

int 21h

 

cmp al,'y'

;якщо натиснута клавіша Y, то

jz IsAfternoon

;Команда переходу

cmp al,'n'

 

jz IsMorning

IsAfternoon:mov dx,OFFSET TiObedal mov ah,9

int 21h mov ah,1 int 21h cmp al,'y' jz IsObedal cmp al,'n'

jz IsNeObedal IsObedal:

mov dx,OFFSET Obedal jmp SHORT Disp IsNeObedal:

mov dx,OFFSET NeObedal mov ah,9

int 21h

mov ax,4C00h int 21h IsMorning:

mov dx,OFFSET TiZavtrakal mov ah,9

int 21h mov ah,1 int 21h cmp al,'y'

jz IsZavtrakal cmp al,'n'

jz IsNeZavtrakal IsZavtrakal:

mov dx,OFFSET Zavtrakal jmp SHORT Disp IsNeZavtrakal:

mov dx,OFFSET NeZavtrakal Disp:

mov ah,9 int 21h Exit:

mov ax,4C00h int 21h

END Start

53

Окрім розглянутих вище команд безумовного переходу, в системі команд х86 є 17 команд умовного переходу, які, як і команда JMP SHORT label, забезпечують короткий перехід в сегменті в діапазоні -128 ... +127 байтів щодо адреси наступної команди. Всі вони мають 2-байтний формат; причому в другому байті міститься зсув (ціле із знаком), який розширюється знаковим розрядом до слова і складається з вмістом IP, якщо на момент виконання команди задана її мнемокодом умова виконана, інакше цей зсув не додається до IP і, отже, перехід не здійснюється. Мнемокоди команд умовних переходів описані в додатку 1, при цьому слід враховувати, що деякі команди умовних переходів мають два, а то і 3 різних мнемокодів, наприклад, команди JB, JNAE і JC мають абсолютно ідентичний машинний код, але надають різне контекстне "забарвлення" програмі:

JB

label

;

перехід, якщо "нижче" (CF=l)

дорівнює"

JNAE label

;

перехід,

якщо "не вище і не

(CF=1)

label

;перехід,

якщо

виникло

JC

перенесення/займання, тобто (CF=1)

Програміст вибирає з цих трьох рівноцінних команд ту, яка на його думку краще відображає умову переходу. Команди умовного переходу використовуються після арифметичних, логічних і інших команд, що впливають на прапорці, для галуження алгоритму залежно від результату виконання команди. Особливо важливо правильно використовувати команди умовних переходів після команди порівняння, оскільки розшукуєтся відмінність між порівнянням чисел із знаком і без знаку:

СМР ор1,ор2

 

;ор1 і ор2

числа із знаком або без знаку

перехід, якщо

op1 > ор2

JG

(JNLE)

JA

(JNBE)

ор1 >= ор2

JGE

(JNL)

JAE

(JNB, JNC)

 

 

opi < ор2

JL

(JNGE)

JB

(JNAE, JC)

 

 

ор1

<= ор2

JLE

(JNG) JBE

(JNA)

 

 

ор1

= ор2

JE

(JZ)

 

JE

(JZ)

 

 

ор1

<> ор2

JNE

(JNZ)

JNE

(JNZ)

 

 

Якщо потрібно здійснити умовний внутрішньосегментний довгий або навіть міжсегментний умовний перехід, то застосовується наступний прийом.

Jcc

No_Jump

;обхід JMP по протилежній умові

JMP

NEAR PTR або JMP FAR PTR ;по необхідній умові

No_Jump

... ;продовжити, якщо потрібна умова не виконана.

Наприклад, якщо за умови АН > AL (без знаку) потрібно перейти на мітку Too_Big в іншому сегменті, то це можна запрограмувати так:

СМР AH,AL

;порівняти операнди

 

JBE

Cont

;обійти перехід, якщо АН <= AL

JMP

FAR PTR Too_Big ;перейти, якщо АН >

AL

54

Cont

...

;продовження, якщо немає переходу по

умові

Використовуючи команди умовних і безумовних переходів, можна реалізувати різні види галуження в програмі, у тому числі і цикли. Але для реалізації циклів з певним числом повторень в системі команд х86 є спеціальні команди управління циклами, кожна з яких при виконанні зменшує на 1 вміст CX, а потім використовує його нове значення для ухвалення рішення про перехід:

LOOP

label

;продовжити з label, якщо СХ не рівний 0

 

LOOPE label

;продовжити з label, якщо СХ не рівний 0 і

;ZF-1, т .е. повторення циклу припиняється якщо СХ = 0 або ZF

;стане рівний 0

;продовжити з label, якщо СХ не рівний 0

 

LOOPNE label

;і ZF = 0, тобто

повторення циклу припиняється

;якщо СХ = 0 або

ZF стане рівний 1

Для команди LOOPE є еквівалент LOOPZ, а для команди LOOPNE - LOOPNZ. Очевидно, що перед входом в цикл потрібно підготувати лічильник циклів в СХ, для запобігання входу в цикл з нульовим значенням СХ корисно використовувати команду короткого переходу.

JCXZ

label

;перехід, якщо СХ = 0

При використанні умовних команд управління циклом в тілі циклу повинні бути команди, що впливають на прапор ZF.

;Фрагмент програми підрахунку кількості додатних (SI) і ;від’ємних (DI) елементів в масиві цілих чисел ARR (слова) ;кількість елементів масиву міститься в СХ.

;Підрахунок припиняється, якщо виявиться нульовий елемент в масиві

SUB

BX,BX;підготовка

покажчика елементів

масиву

MOV

SI,BX

DI,BX

 

 

 

 

MOV

 

 

 

 

JCXZ

Exit ;обхід, якщо нульова кількість елементів

з

Again:

CMP

Агг[BX],0

;порівняти

черговий

елемент

нулем

Exit

 

;завершити,

якщо

нульовий

JE

 

елемент

Great

;> 0

 

 

 

JG

 

 

 

INC

DI

 

;підрахунок від’ємних

 

 

JMP

SHORT Next

;підрахунок додатних

 

 

Great

INC

SI

 

 

Next:

ADD

BX,2

;покажчик на наступний елемент

LOOP Again

;продовжити,

якщо

не

всі

оброблено

...

 

 

 

 

 

EXIT

 

 

 

 

 

55

Контрольні питання

1.Від чого залежить довжина команд безумовного переходу?

2.Яка інформація про перехід міститься в команді для безумовного переходу усередині сегменту?

3.На які групи можна розділити команди умовних переходів?

4.Які способи адресації можна використовувати для непрямого внутрішньосегментного переходу?

5.Які існують можливості для здійснення прямого міжсегментного

переходу?

Індивідуальні завдання

1.Написати програму перетворення рядкових букв заданого рядка символів в прописні букви.

2.Написати програму ущільнення тексту за рахунок заміни двох і більш пропусків одним пропуском.

3.Реалізувати програмно наступну конструкцію вибору

dо case X mod 4

Y = 3 * (X + 437) / (Z - 4128) ; Y = (Х - Z +1289) / X ;

Y = (X - 654) / (4 * Z) ;

Y = 255 * X / (X + Z - 12985) ; end

4.Написати програму впорядковування в алфавітному порядку таблиці, що містить десять 2-символьних слів.

5.Написати програму підсумовування чисел масиву (20 елементів), що належать діапазону від MIN до МАХ. Числа в масиві розглядаються як беззнакові величини (слова), результат додавання реалізувати у вигляді подвійного слова.

6.Програмно реалізувати сортування після убування масиву цілих чисел із знаком (15 слів), застосовуючи алгоритм "бульбашкового" сортування по схемі ПОВТОРЮВАТИ – ПОКИ :

repeat

послідовність дії until (вираз)

7.Написати програму, яка перетворює рядки мнемокодів команд

MOVSB, MOVSW, LODSB, LODSW, STOSB, STOSW, SCASB, SCASW, CMPSW (у довільному порядку) у відповідні двійкові коди машинних команд.

8.Написати програму, яка виконує функцію реасемблювання машинних кодів, приведених в завданні 7 команд, у відповідні мнемокоди.

9.Написати програму, яка сканує символи з рядка, перевіряє їх на належність 16-ковим цифрам і до тих пір, поки не з'явиться символ, відмінний від 16-кової цифри, формує з кожної пари цифр відповідне двійкове значення і записує його в байтовий масив

56

10.Написати програму пошуку заданого ланцюжка символів в деякому текстовому масиві, ознакою завершення якого є код 1Ah.

11.Написати програму підсумовування елементів масиву (20 слів в беззнаковому поданні), яка зупиняє свою роботу, якщо сума перевищила значення 65535 або якщо оброблені всі елементи масиву (суму формувати у вигляді подвійного слова) Використовувати схему

do while (вираз)

послідовність дій end

12.Написати програму, яка переставляє в зворотному напрямку букви

всловах заданого рядка в ASCIIZ-форматі.

13.Написати програму, яка підраховує частоту використання букв в деякому заданому тексті, представленому в ASCIIZ-формате.

14.Написати програму, яка в заданому рядку визначає число слів (роздільники слів. пропуск, кома, крапка, крапка з комою, тире) і встановлює довжину найбільш довгого слова в рядку.

Додаток 6.1 Приклади виконання індивідуальних завдань. Програма-діалог «Добра порада!», створена студентом 411-ОКС групи

Дроновим Олександром.

 

 

ideal

small

 

 

model

 

 

Stack

256

 

 

Dataseg

 

Promt

db

13,10,'Здоров друже! Хочеш добру пораду? (Так/Нi - y/n)$'

VitNo

db

13,10,'Як знаєш. Бувай!$'

VitYes

db

13,10,'Ти жiночої статi? (Так/Нi - y/n)$'

Man

db

13,10,'Гаразд, ти навчаєшся? (Так/Нi - y/n)$'

ManNo

 

db

13,10,'Ти працюєш? (Так/Нi - y/n)$'

ManNo1

db

13,10,'Ти пенсiонер? (Так/Нi - y/n)$'

ManPor

db

13,10,'Ось тобi порада, ЛЕДАЦЮГА!!! Якщо не будеш працювати,',13,10,'то

швидко "полетиш" за грати! Нiхто тебе не пригадає,',13,10,'нi теплим словом привiтає. Якщо ж ти будеш працювати,',13,10,'тебе всi будуть поважати, дорба i щастя вам бажати!!!$' ManYes db 13,10,'Якщо ти добре будеш працювати, то грошенят багато будеш мати,',13,10,'з грошима ти в життi не згинеш, до неба з думкою про них полинеш,',13,10,'Але не задирай ти високо свiй нiс! Бо повезуть тебе в багажнику у лiс!$'

ManNAV db 13,10,'Повинен зараз добре ти навчатись, щоб потiм до дiвчат з вiршами залицятись,',13,10,'дiвчата люблять слухати вiршi, тому одраз до серця будеш линути їм ти!$' ManPen db 13,10,'В країнi нашiй ти на пенсiю не проживеш!',13,10,'Скорiш за все ти ноги передчасно простягнеш,i з вдачею такою у тей свiт минеш!',13,10,'Ото ж вставай, шукай собi роботу, поки не задзвонили родичi в "СКОРБОТУ"!$'

Woman

db

13,10,'О... Це добре! Ти навчаєшся? (Так/Нi - y/n)$'

WomNo

db

13,10,'Ти працюєш? (Так/Нi - y/n)$'

WomNo1

db

13,10,'Ти вродлива? (Так/Нi - y/n)$'

WomNAV

db

13,10,'Якщо ти незалежна хочеш бути, i нареченого свого у чоботи

обути,',13,10,'всi сили ти повинна зараз на навчання вiддавати, щоб потiм гiдно працювати!$' WomYes db 13,10,'Якщо ти працюватимеш ти на славу, то витягнеш зi звалища державу.',13,10,'Тобi пiдвладнi будуть всi кордони, й не заважатимуть нiякi перепони!$'

57

WomWro db 13,10,'Тобi на свiтi легко жити, ти можеш хлопцям голову дурити,',13,10,'але цей час мине колись, нiчого ти не вдiєш, як ти не крутись!',13,10,'Та щоб в iсторiї залишити свiй слiд, повинна ти за розум взятися як слiд!$'

WomPor db

13,10,'Всiм крокодилам у життi не пощастило, нi розуму нi красоти, а тiльки

сила!',13,10,'В

життi тобi не легко буде жити, але не дай собi над цим весь час

тужити!',13,10,'Та прийде час i вже не будеш ти тужити - бо будеш в всесвiтi найкраще жити!$'

Codeseg

START:

mov ax,@data mov ds,ax

mov dx,OFFSET Promt

;Привiт друже, хочеш добру пораду?

mov ah,9

 

 

int 21h

 

 

mov ah,1

 

 

int 21h

 

 

cmp al,'y'

;Так

 

jz VitYesOK

;Стрибок на "Ти жiночої статi?"

cmp al,'n'

;Нi

 

jz exitOZ

;Стрибок на "Як знаєш, бувай!"

exitOZ:

 

 

mov dx,offset VitNo

 

mov ah,9

 

 

int 21h

 

 

mov ax,4c00h

 

 

int 21h

 

 

VitYesOK:

 

 

mov dx,OFFSET VitYes

;Ти жiночої статi?

mov ah,9

 

 

int 21h

 

 

mov ah,1

 

 

int 21h

 

 

cmp al,'y'

;Так

 

jz WomanOK

;Стрибок на "О... Це добре! Ти навчаєшся?"

cmp al,'n'

;Нi

 

jz ManOK

;Стрибок на "Гаразд, ти навчаєшся?"

WomanOK:

 

 

mov dx,OFFSET Woman ;О... Це добре! Ти навчаєшся?

mov ah,9

 

int 21h

 

mov ah,1

 

int 21h

 

cmp al,'y'

;Так

jz WomNAVOK

;Стрибок на "Ти незалежна хочеш бути...

cmp al,'n'

;Нi

jz WomNoOK

;Стрибок на "Ти працюєшь?"

ManOK:

mov dx,OFFSET Man mov ah,9

int 21h mov ah,1

58

int 21h cmp al,'y'

jz ManNavOK cmp al,'n'

jz ManNOOK WomNoOK:

mov dx,OFFSET WomNo mov ah,9

int 21h mov ah,1 int 21h cmp al,'y'

jz WomNAVOK cmp al,'n'

jz WomNo1OK WomNo1OK:

mov dx,OFFSET WomNo1 mov ah,9

int 21h mov ah,1 int 21h cmp al,'y'

jz WomWroOK cmp al,'n'

jz WomPorOK ManNoOK:

mov dx,OFFSET ManNo mov ah,9

int 21h mov ah,1 int 21h cmp al,'y'

jz ManYesOK cmp al,'n'

jz ManNo1OK ManNo1OK:

mov dx,OFFSET ManNo1 mov ah,9

int 21h mov ah,1 int 21h cmp al,'y'

jz ManPenOK cmp al,'n'

jz ManPorOK

WomNAVOK:

mov dx,OFFSET WomNAV mov ah,9

int 21h mov ah,1 jz Exit

59

ManNAVOK:

mov dx,OFFSET ManNAV mov ah,9

int 21h mov ah,1 jz Exit WomWroOK:

mov dx,OFFSET WomWro mov ah,9

int 21h mov ah,1 jz Exit ManYesOK:

mov dx,OFFSET ManYes mov ah,9

int 21h mov ah,1 jz Exit ManPenOK:

mov dx,OFFSET ManPen mov ah,9

int 21h mov ah,1 jz Exit WomPorOK:

mov dx,OFFSET WomPor mov ah,9

int 21h mov ah,1 jz Exit ManPorOK:

mov dx,OFFSET ManPor mov ah,9

int 21h mov ah,1 jz Exit

Exit:

Int 21h

mov ax,4c00h int 21h

end start

Програма з паролем, створена студентом групи 411-ОКС-2004 Яворським Володимиром Володимировичем.

Принцип роботи програми з паролем поданий на рисунку 6.1.

60