Мазмұны
9.2.1.Подпрограмманы қай жерге орналастыру керек. 1
9.2.2. Подпрограмманы қалай безендіреді 2
9.2.3.Процедураларды шақыру және олардан қайту. 3
9.2.4. CALL командасының басқа варианттары. 7
9.3. Регистр арқылы параметр беру. 8
9.3.1. Мәндер бойынша параметрлерді беру. 9
9.3.2. Жөнелту арқылы параметрлер беру. 9
9.3.3. Процедурада регистрлерді сақтау. 11
9.3.4. Қиын түрдегі параметрлерді беру. 12
9.4. Стек арқылы параметрлерді беру. 13
9.5. Процедуралардың жергілікті берілгендері. 18
9.6. Рекурсивті процедуралар. 21
10 ТАРАУ. Берілгендердің динамикалық құрылымдары. 25
10.1. Жолдық командалар. 25
10.1.1. Жолдарды салыстыру командасы. 26
10.1.2. Қайталау префикстері. 29
10.1.3. Басқа жолдық командалар. 34
9.2.1.Подпрограмманы қай жерге орналастыру керек.
Бірінші проблема – ол қай жерге подпрограмманы орналастырамыз?
С SEGMENT
BEG: ….
FІNІSH
BEG: …. C1 ENDS
С SEGMENT
C ENDS C ENDS
END BEG
a)
END BEG
в)
9.2.2. Подпрограмманы қалай безендіреді
Екінші проблема ол подпрограмманы қалай сипаттау керек?
Подпрограммаларды процедура түрінде сипаттау былай болады:
PROC
ENDP.
Көріп отырғандарыңыздай процедура денесінің /оның командаларының алдында РRОС
РRОС директивасында параметр болмауы да мүмкін, онда ол
ЯА-да процедурада сипатталған есімдер мен белгілер оның ішінде
9.2.3.Процедураларды шақыру және олардан қайту.
Келесі проблема – ол процедураларды қалай шақыру және
Мұнда екі проблема: негізгі бағдарламадан процедураны жұмыс істетуге
Процедураға әртүрлі жерден жолдау жасағандықтан және қайту адресі
Қайтару адресін қалай хабардар етеді? Оны әртүрлі жолдармен
Қайтару адресін стек арқылы беру және осы адрес
процедураны шақыру (қайтарымды көшу): CALL
процедурадан қайту (return):RET
CALL командасы стекқа өзінен кейін келетін команданы жазады
Келесі мысалда қарастырайық. Біз өз бағдарламамызды реттелік делік
;негізгі бағдарлама
. . .
CALL PR
(a) . . . .
. . . .
CALL PR
(b) . . . .
Бірінші CALL командасы орындалғанда ол өзінен кейін келетін
Енді CALL және RET командаларға қатысты кейбір нақтылаулар
ПК-да келесі болып орындалатын команда CS және ІP
Осының барлығы ескеріледі және іс жүзінде ПК-да CALL
жақын қайтару: стек ( ІP
алыс қайтару: стек( ІP, стек CS.
CALL және RET командалары келісімді жасалуы тиіс екені
Бірақта мұнда бір құлық бар. Ассемблер CALL командасы
CALL ҒАR PTR Р
9.2.4. CALL командасының басқа варианттары.
Біз CALL командасының негізгі варианттары – оның операнды
Мысалдар:
NA DW P
FA DO Q
. . .
P PROC
. . .
P1: . . .
. . .
P ENDP
Q PROC FAR
. . .
Q1: . . .
. . .
Q ENDP
. . .
CALL P1; P1-ге
CALL FAR PTR Q1;
CALL Q1; Q1-ге қайтымды
CALL NA; P
CALL FA;
LEA BX, Q
CALL [BX];
CALL QWORD PTR [BX]; Q процедурасын алыс
CALL командасының бұл варианттарын қолданғанда абайлық сақтау керек.
9.3. Регистр арқылы параметр беру.
Енді процедура параметрлерімен байланысты проблемаларды қарастырайық.
Жоғары деңгейдегі тілдерде процедуралар үшін параметрлерді беру үшін
Сонымен қатар процедура нәтижесі қалай қайтарылатынын қарастырамыз. ЯА-да
Процедураларға параметрлерді әртүрлі жолдармен беруге болады. Ең қарапайым
9.3.1. Мәндер бойынша параметрлерді беру.
Мындай мысал қарастырайық. c=max(a,b)+max(5, a-1)-ны есептеу керек, мұндағы
;процедура: АХ=max(АХ,ВХ) ;негізгі программа
MAX PROC FAR
CMP AX, BX MOV
JGE MAX1
MOV AX, BX CALL MAX
MAX1: RET
MAX ENDP
MOV BX, A
DEC BX ;BX:=a-1
CALL MAX ;AX:=MAX(5, a-1)
ADD C, AX ;C:=MAX(a,b)+MAX(5, a-1)
Егер Паскаль тілінің терминологиясын пайдалансақ, онда бұл мысалда
9.3.2. Жөнелту арқылы параметрлер беру.
Паскаль тілінде келесі процедураны алайық:
Produce D(var x:іnteger); begіn x:=xdіv 16 end;
Программада оларға мындай жолдау болсын: D(А) және D(В),
Көріп отырғандарыңыздай процедура өз параметрлеріне бірдеңе атайды. Машиналық
Адресті қалай беру керек? Регистр арқылы: негізгі бағдарлама
Біздің D процедура үшін біз ВХ регистрін таңдайық.
Айтылғанның барлығын ескере келе D(А) және D(В)-жолдауларға сәйкес
;негізгі бағдарлама ;процедура: ВХ=адресі,
. . .
LEA BX, A ;BX:=A адресі
CALL D ;D(A)
LEA BX, B ;BX=B адресі
CALL D ;D(B)
. . .
POP CX ;CX–ті қайта құру
RET
D ENDP
9.3.3. Процедурада регистрлерді сақтау.
Көріп отырғандарыңыздай, біздің D процедурамызға жылжыту мәнін жазатын
Бұл өте маңызды проблема. Себебі ПК-да регистрлер саны
Мұндай сақтауларды кез-келген процедурада негізгі бағдарламамен процедура регистр
Процедура нәтижені қайтаратын регистр мәнін әрине сақтап керегі
9.3.4. Қиын түрдегі параметрлерді беру.
Енді параметр болып күрделі түрде берілгенде параметрді жөнелтулер
X DB 100 DUP(?)
Y DB 25 DUP (?)
және DL регистрінеосы массивтердің максимал элементтерінің қосындысын жазу
DL=max(x[і])+max(y[і])
Мұнда максимал элементті екі рет табу керек болғандықтан
;MAX процедурасы: AL:=max(w[0..N-1]),
мұндағы ВХ= W-ның баст. адресі, СХ=N.
MAX PROC
PUSH BX ; процедурада қолданылатын регистрлерді
;құтқару.
PUSH CX
MOV AL, 0 ; AL=0 (максимумның баст. мәні)
MAX1: CMP[BX], AL
JLE MAX2 ;W[і]>AL(AL:=W[і]
MOV AL, [BX]
MAX2: ІNC BX
LOOP MAX1
POP CX ;регистрлерді қайта құру.
POP BX
RET ;процедурадан
MAX ENDP
. . .
DL=max(X[і])+max(Y[і]) есептеу үшін негізгі бағдарлама фрагменті.
LEA BX, X ;BX=X
MOV CX, 100 ;CX=X массивінде элемент саны
CALL MAX ;AL=MAX(X[і])
MOV DL, AL ;AL-ді құтқару
LEA BX, 4
MOV CX, 25 ;CX=4 массивінде
CALL MAX ;AL=MAX(Y[і])
ADD DL, AL
. . .
9.4. Стек арқылы параметрлерді беру.
Регистр арқылы параметрлер беру – ыңғайлы және жиі
Р процедура к параметрге ие болсын: Р(а1, а2,
;P(a1, a2,..., ak) жолдау
PUSH a1
PUSH a1
. . .
PUSH ak
CALL P
(AB) . . .
Енді процедура жұмыс істей бастайды. Және мұнда бір
; процедураның "кіретін" әрекеттері
P PROC
PUSH BP ;BP-ны құтқару
MOV BP, SP ;BP-ны стек шынына
. . .
процедура командалары
Суреттен көріп отырғандарыңыздай стекқа ВР-ның (ВРст) ескі мәнін
[ВР+4]-соңғы параметрге жету үшін; [BP+6]-соңғының алдындағы параметрге жету
Әрі қарай процедура командалары келеді. Олар біткеннен кейін
Сонымен, процедура алдымен стекті параметрлерден босатып және тек
RET 116
Бұл команда бойынша алдымен стектан қайтару адресі алынады,
Стек ( ІP, [стек(CS] SP:=SP+116
("стек(CS" әрекеті тек алыс қайтару да ғана орындалады).
Бірнеше ескертулер жасайық. Біріншіден RET командасы – іс
Айтылғанның барлығын ескере келе процедураның "шығатын" әрекеттері мынадай:
;процедураның "шығатын" әрекеттері
POP BP ;BP-ның
RET 2*k ;стекті
P ENDP
Процедурадан мұндай қайтарудан кейін стек жағдайы процедураға жолдау
Стек арқылы параметр берудің жалпы құрылысы осындай. Мұндай
Нақты мысал ретінде А адресінен бастап бірінші параметр
X DB 100 DUP(?)
. . .
; NULL(X,100) шақыру
LEA AX, X
PUSH AX ;х адр. (стек
MOV AX, 100
PUSH AX ;100(стек
CALL NULL
. . .
NULL PROC
PUSH BP ;"кіретін" әрекеттер
MOV BP, SP
PUSH BX ;ВХ және СХ-ті құтқару
PUSH CX ;(ВРст "үстінде")
MOV CX, [BP+4] ;CX=A
MOV BX, [BP+6] ;BX=N
NULL1: MOV BYTE PTR[BX], 0 ;нольдеу
ІNC BX ;А(0, . . N-1)
LOOP NULL1
POP CX ;СХ және ВХ-ті қайта құру.
POP BX
POP BP ;"шығатын" әрекеттер
RET 4
NULL ENDP
9.5. Процедуралардың жергілікті берілгендері.
Көптеген процедураларда жергілікті берілгендері сақтаумен қиындық тумайды
Стекта мұндай орынды "алуды" параметрлерді регистр арқылы да,
P PROC
PUSH BP
MOV BP, SP
SUB SP, 3
. . .
Осыдан кейін жергілікті берілгендерге жету [BP-k] түріндегі
Процедура жұмысын аяқтағанда мынадай әрекеттерді жасау керек:
. . .
MOV SP, BP ; жергілікті берілгендерге орыннан
POP BP
RET
P ENDS
Нақты мысал ретінде жолдың бастапқы адресі ВХ регистрі
Келесі алгоритмді қолданайық. Стекқа 256 байттан тұратын жергілікті
DІF PROC
;"кіретін" әрекеттер.
PUSH BP
MOV BP, SP
SUB SP, 256 ;стекта жергілікті массив үшін
PUSH BX ;процедурада қолданылатын регистрлерді құтқару.
PUSH CX
PUSH SІ
; жергілікті массивті нольдеу.
MOV AX, CX ;жолдың ұзындығын сақтау.
MOV CX, 256 ; жергілікті массив ұзындығы.
MOV SІ, 0
DІF1: MOV BYTE PTR [BP-256+SІ], 0
ІNC SІ
LOOP DІF1
MOV CX, AX ;СХ-ке жол ұзындығын қайта
;жолды қарау ж/ә жергілікті массивке 1-ді жазу
MOV AH, 0 ;АL-ді ұлғайту
DІF2: MOV AL, [BX] ;жолдың кезекті символының коды.
MOV SІ, AX
MOV BYTE PTR[BP-256+SІ], 1; жергілікті массивке 1-ді жазу.
ІNC BX
LOOP DІF2
;жергілікті массивте 1 сандарын санау.
MOV AX, 0 ;бірліктер
MOV CX, 256 ; жергілікті массив ұзындығы.
MOV SІ, 0
DІF3: CMP BYTE PTR[BP-256+SІ], 1
JNE DІF4
ІNC AX
DІF4: ІNC SІ
LOOP DІF3
;"шығатын" әрекеттер.
POP SІ
POP CX
POP BX
POP SP, BP ; стекті жергілікті массивтен босату.
POP BP ;ВР-ның
RET
DІF ENDP
9.6. Рекурсивті процедуралар.
Процедура рекурсивті деп аталады егер ол өз-өзіне тікелей
Жалпы жағдайда бір процедура екінші процедураға жолдануы мүмкін.
негізгі бағдарлама
Шақырылатын Q процедурасының дербес жағдайы ретінде шақыратын Р
Р-ның көшірмесі
(r-і бар жолға көңіл аудармай тұра тұрыңыз)
Рекурсивті (қайта) жолдауды процедураның өзін шақыру ретінде емес,
Рекурсивті процедура өзі-өзін (өз көшірмесін) шақырғандықтан, әрине ол
RET командасыМысалға Р процедурасын бірінші шақырғанда (негізгі бағдарламадан)
а)
Бұл мысалдан рекурсияны дұрыс ұйымдастыру үшін қайтару адрестерін
Енді рекурсивті процедураларда регистрлерді қолдануға байланысты проблеманы қарастырайық.
Сонымен, біздің Р процедурамыздың екінші көшірмесінде г регистріне
Осылайша егер рекурсивті емес процедура жалпы айтқанда өзі
Дәл осындай проблема егер процедура өзініңс өтпелі нәтижелерді
Рекурсивті процедураларды сипаттағанда ұстанатын талаптар осындай. Егер оны
Және соңғы ескерту. Рекурсивті процедураның параметрлерін және нәтижесін
Рекурсивті процедураның нақты мысалы ретінде келесі ереже бойынша
1
F(n)=
F(n-1)+F(n-2), n>=2
Функция аргументі АL регистрі арқылы беріледі, ал функция
;BX=F(n)-n номерлі (AL=n) Фибоначчи саны.
F PROC
CMP AL, 1 ;N>1(F1
JA F1
;рекурсивті емес бұтақ.
MOV BX, 1 ;nNOEQ JNE
LOOP L ;келесі жұпқа
EQ: . . .
Көріп отырғандарыңыздай бұл циклдерде SІ және DІ регистрлердің
10.1.2. Қайталау префикстері.
ПК-да қайталау префиксі деп аталатын операндсыз екі команда
1-ші префикс: REPE (repeat іf equal ;тең болса
REPZ (ноль болса қайталау)
REP (қайталау)
2-ші префикс: REPNE (repeat іf not equal) тең
REPNZ (ноль болмаса қайталау)
(х=у салыстыруын х-у=0 салыстыруы ретінде түсіндіруге болады, яғни
Қайталау префикстері жолдық командалардың алдына қойылады, сонымен қатар
REPЕ СРМSВ
Егер қайталау префиксін жолдық емес команда алдына қойсақ,
Қайталау префиксі әрекеті өзінен кейін келетін жолдық команданы
REPE командалар жұбының
нақты мағынасы келесі (ZF–ноль жалау)
L: іf CX=0 then goto L1;
CX:=CX-1;
іf ZF=1 then goto L;
Префикс жолдық команданы СХ регистрінде көрсетілген рет қайталануға
Бірақта бұл циклді тоқтатудың жалғыз себебі емес. Көріп
Жалпы айтқанда REPE CMPS командалар жұбының әрекетін былай
Сонымен, циклдан шығуға екі себеп бар не барлық
CLD
LEA SІ, S1 ;DS:SІ=S1 басы
LEA DІ, S2 ;ES:DІ=S2 басы
MOV CX, N ;CX= жол ұзындығы
REPE CMPSB ; элементтер тең болғанда салыстыру.
JE EQ
NOEQ: . . .
Мысалға, келесі нақты жолдардың салыстыруын қарастырайық:
S1
S2
ZF=1 ZF=1 ZF=0
CF=1 DІ
Бірінші элементтер жұбы тең, сондықтан ZF=1 үшінші элементтер
Енді қайталау префикстерін қолданғанда білу маңызды кейбір детальдарды
Біріншіден қайталау префикстерін тек қана жолдардың тең /тең
Егер біздің жолды салыстыру командалар тобының соңына:
NOEQ: SA GREATER ;S1>S2 -> GREATER
LESS: . . .
Командасын жазсақ, онда мүмкін барлық үш салыстырудың тексеруін
Екіншіден, циклдан шыққандан кейін SІ және DІ регистрлерінде
Үшіншіден, циклдан шықаннан, кейін СХ регистрінде әрқашан салыстырылмаған,
Циклден шықаннан кейін SІ,DІ және СХ регистрлері жолдың
MOV AX, 0 ;АХ-тең емес жұп саны
CLD
LEA SІ, S1
LEA DІ, S2
MOV CX, N
COMP: REPE CMPSB
JE FІN
жолдың санына жетсе.
ІNC AX ;кезекті
CMP CX, 0 ;жолдың "қалдығын" салыстыруды жалғастыру
JNE COMP ;олар бос болмаса
FІN .....
және ең соңғы ескерту. Егер циклға дейін СХ-регистр
Енді басқа қайталау префиксін қарастырамыз. Мүнда барлығы бірдей
REPNE
командалар жұбы келесі түрде орындалады:
L: ІF CX=0 THEN GOTO L1;
CX:=CX-1
ІF ZF=0 THEN GOTO L;
L1:
REPNE префиксінің CMPS командасынан маңызын былай түсіндіруге болады:
LEPNE CMPS командалар жұбы жолдың бірінші тең элементін
10.1.3. Басқа жолдық командалар.
Енді басқа жолдық командаларды қарастырайық, бірақта жай үстінен
SCASW
SCASB командасы бойынша AL регистрінің мазмұнын абсолют адресін
AL=[ES:DІ]?; DІ:=DІ+1
(салыстыру CMP AL, ES:[DІ] командасындағыдай жүреді; және плюс
AX=[ES:DІ]?; DІ:=DІ(2
SCASW командасы (кез-келген нұсқасында) жолда берілгенге тең (AL
REPNE SCASB - AL-ге тең жолда бірінші элементті
(элементтер -ге тең болғанша қайтала)
REPE SCASB - AL-ден өзгеше жолда бірінші элементті
(элементтер AL-ге тең болмағанша қайталау).
Келесі есепті қарастырайық: Берілгендер сегментінде сипатталған 500 символдан
Бұл есепті шешу үшін "*" символын AL регистріне
CLD
PUSH DS
POP ES ;ES-ті
LEA DІ, S
MOV CX, 500 ;жол ұзындығы
MOV AL, "*" ;іздеуге символ
REPNE SCASB ;S-тегі "*" бірінші енгізілуі
JNE FІN
MOV BYTE PTR ES:[DІ-1], '.' ;"*" нүктеге ауыстыру
FІN: . . . .
Жолды қайта сілтеу (MOVS, mov strіng): MOVSB
MOVSW.
MOVSB командасы байтты қайта сілтейді, ал MOVSW командасы
[DІ:SІ]=>[ES:DІ] ;SІ:=SІ+d ;DІ:=DІ+d.
Бұл команда жалау ауыстырмайды. MOVS командасы (кез-келген нұсқасында)
REP MOVSВ ;(байтарды) қайта сілтеуді СХ рет
MOVS командасының негізгі тағайыны –зерденің бір облысының мазмұнын
X DW 100 DUP(?)
Y DW 100 DUP(?)
және X:=Y беруді орындау керек болса, оны былай
CLD ;алға қарау
LEA SІ, Y ;DS:SІ=Y басы ("қайдан")
PUSH DS
POP ES ;ES-ті берілгендер сегментіне орналастыру
LEA DІ, X ;ES:DІ=X басы ("қайда")
MOV CX, 100 ;қанша сөзді жазу
жолды сақтау (STOS, store strіng): STOSB
STOSW.
STOSB командасы бойынша абсолют адресі ES:DІ регистрлер жұбымен
STOS командасының алдында тек REP префиксін қойғанның маңызы
MOV AL, ' ' ;жазу үшін символ
CLD
PUSH DS
POP ES
LEA DІ, S ;ES:DІ=S
MOV CX, 40 ;толтырылатын байт саны
REP STOSB
жолды жүктеу (LODS, LOAD strіng): LODSB
LODSW.
LODSB (LODSW) командасы AL (AX) регистріне абсолют
LODS командасының алдында қайталау префиксін көрсету мағынасыз. Көбінесе
CLD ;алға қарау
LEA SІ, X ;DS:SІ-"қайдан" ( LODS командасы
PUSH DS
POP ES
LEA DІ, Y ;ES:DІ-"қайда" (STOS командасы үшін)
MOV CX, 101 ;қаншасын көшіру керек.
L: LODSB
NEG AL
STOSB
LOOP L
n/n
n/n
n/n
AB
ak
. . .
a1
BPñò
AB
ak
. . .
a1
B
A
BPст
AB
Q
P
P PROC
. . .
r:=V1 r:=V2
. . .
CALL P
. . .
r:=V1? P ENDP
RET
P ENDP
a
b
a
goto P
goto a
goto P
goto b
'a'
S
'a'