Assembler proqramlaşdırma dili

Prosedurların təşkili

Prosedurların təşkili

Kifayət qədər dəqiq məsələlərin proqramlaşdırılmasında bir qrup əmrlər təkrarlanır. Bunlar bəzən kiçik, bəzən isə kifayət qədər böyük yer tutur. Sonuncu halda bu fraq­mentlər proqramın oxunmasını əhəmiyyətli dərəcədə çətinləşdirir, əyaniliyini azaldır, sazlanmasını mürək­kəb­ləşdirir və səhvlərin yaranmasına səbəb olur və s. Proq­ramda kodlar sahəsinin təkrarlanmaması problemini həll etmək üçün Assembler dilində bir sıra vasitələr mövcuddur:

· Prosedur mexanizmi;

· Makroəmr;

· Kəsilmə mexanizmi.

Prosedur (altproqram) – hər hansı məsələnin dekompo­ziya (bir neçə hissəyə bölünməsi) vahidir.Prosedura kon­kret altməsələnin həlli üçün lazım olan əmrlər qrupu olub, ən yüksək səviyyədə məsələdə çağırış nöqtəsindən müraciə­tin idarə olunması və idarənin bu nöqtəyə qaytarma vasitə­lərinə malikdir. Başqa sözlə prosedur müəyyən qayda ilə təyin olunmuş bir dəfə yazılan əmrlər yığımı olub, onu proqramın istənilən yerində yazmaq və ona təkrar-təkrar müraciət etmək olar.

Əmrlər ardıcıllığını prosedur kimi təşkil etmək üçün, assembler dilində PROC və ENDP direktivlərindən istifadə olunur.

Prosedurun sintakiz təsviri aşağıdakı kimidir:

Prosedurun başlığında (PROC direktivi) məcburi para­metr kimi yalnız prosedura ad göstəricisidir.

Məsafə atributu NEAR (yaxın prosedur) və ya FAR (uzaq prosedur) qiymətlərini ala bilər. Susmaya görə məsa­fə atributu NEAR qiymətini alır. NEAR atributlu pro­sedura, yalnız, onun təyin olunduğu əmrlər seqmentindən. FAR atributlu prosedura isə istənilən əmrlər seqmentindən müraciət edilə bilər.

Proseduru proqramın istənilən yerində yerləşdirmək olar. Bunun üçün, prosedurun proqramda yerləşdirilmə­sinin aşağıdakı variantları möcuddur:

- Proqramın əvvəlində (birinci icra olunan əmrdən əv­vəl);

- Sonunda (idarəni əməliyyat sisteminə qaytaran əmrlərdən sonra);

- Aralıq variant – prosedurun gövdəsi başqa prosedurda və ya əsas proqramda yerləşir. Bu halda, prosedura keçidi JMP şərtsiz keçid əmrinin köməyi ilə aparmaq nəzərdə tutulur;

- Başqa modulda.

Birinci variantda prosedur əmrlər seqmentinin başlan­ğıcında birinci icra olunan əmrdən əvvəl yerləşir. Bu halda prosedurdan dərhal sonra (ENDP direktivindən sonra) proqramın icrasına başlanması tələb olunan əmrinin nişanı yerləşməlidir. Bu nişan, proqramın sonunu göstərən END direktivində göstərilməlidir:

MASM
MODEL SMALL
.STACK   100h
.DATA
.CODE
sub_prog PROC  NEAR
...
                 RET
sub_prog ENDP
start:                   ; Birinci əmrin nişanı 
...
END start

İcra olunan proqramın özü də prosedur kimi təşkil oluna bilər və prosedurdan başlayaraq proqram yerinə yetrilir. Bu prosedurun adını END direktivində mütləq göstərilmək lazımdır. Beləliklə, əvvəlki fraqment aşağıdakına ekvivalentdir:

MASM
MODEL   SMALL
.STACK   100h
.DATA
.CODE
sub_prog PROC  NEAR
...
                RET
sub_prog ENDP
start    PROC
...
start    ENDP
         END start

Bu fraqment yaddaşa yükləndikdən sonra, idarə, start adlı prosedurun birinci əmrinə veriləcəkdir.

Proseduru proqramın sonunda yerləşdirmək üçün onu, idarəni əməliyyat sisteminə qaytaran əmrlərdən sonra yerləşdirmək lazımdır.

MASM
MODEL   SMALL
.STACK   100h
.DATA
.CODE
start:
…
           MOV AX,4C00h
           INT 21h               ; idarənin ƏS qaytarılması
sub_prog PROC  NEAR
…
           RET
sub_prog ENDP
END start

Prosedurun aralıq variantda yerləşməsi halında prosedura keçidi, JMP şərtsiz keçid əmrinin köməyi ilə aparmasını nəzərə almaq lazımdır:

MASM
MODEL   SMALL
.STACK   100h
.DATA
.CODE
start:
…
       JMP   nish
sub_prog PROC NEAR
…
        RET
sub_prog ENDP
nish:
…
       MOV AX,4C00h
         INT 21h               ; idarənin ƏS qaytarılması
END start

Prosedurun ayrı modulda və ya ayrı kodlar seqmentində yerləşməsi variantına tez-tez istifadə olunan prosedurun ayrı faylda yerləşdirilməsi variantı kimi baxmaq olar. Bu fayl adi ilkin fayl kimi təşkil olunur və ayrıca translyasıya olunar obyekt modul kimi yaradıla bilər və əsas proqramla TLINK utilitinin köməyi ilə birləşdirilir.

Prosedurlara müraciət CALL əmri vasitəsi ilə olur. O aşağıdakı formata malikdir:

CALL [modifikator] prosedurun _adı

CALL əmri JMP əmrinə analojidir, idarəni prosedurun simvolik adına ötürür, ancaq bu halda qayıtma ünvanı stekdə saxlanır. Qayıtma ünvanı - CALL əmrindən sonrakı növbəti əmrin ünvanıdır.

JMP əmrində olduğu kimi, prosedurun CALL əmri ilə çağrılması aşağıdakı hallarda ola bilər:

seqmentdaxili – yəni prosedur NEAR tipə malik olub, cari kodlar seqmentində yerləşir və qayıtma ünvanı kimi CALL əmri yalnız IP/EIP registrinin məzmununu saxlayır;

seqmentlərarası. Bu halda prosedur FAR tipə malik olub, başqa kodlar seqmentində yerləşir və qayıtma ünvanı kimiCALL əmri hər iki IP/EIP və CS registrlərinin məz­mun­larını saxlayır. Onların saxlanma ardıcıllığı: əvvəlcə stek­də CS registrinin sonra isə IP/EIP registrinin məzmun­larını saxlanır.

Qayıtma ünvanı saxlandıqdan sonra əgər prosedur NEAR atributuna malikdirsə CALL əmri prosedurun _adı nişanının sürüşmə ünvanını IP əmr göstəricisi registrinə yükləyir.

Qeyd edək ki, eyni bir prosedur yaxın və ya uzaq tipli prosedur ola bilməz.

Prosedur icra olunduqdan sonra idarəni qaytarmaq üçün RET əmrindən istifadə olunur. Bu əmr prosedurun icrasından sonra idarəni, proseduru çağıran proqramdakı CALL əmrindən sonra gələn əmrə qaytarır. RET əmri prosedurun sonuncu icra olunan əmri olub, aşağıdakı kimi göstərilir:

RET [ədəd]

RET əmri qayıtma ünvanını stekdən oxuyur. Əgər prosedur NEAR atributlu isə, onda RET əmri qayıtma ün­vanını IP/EIP registrinə, FAR atributlu olduqda isə IP/EIP və CS registrlərinə yükləyir. Sonuncu halda, əv­vəlcə IP/EIP, sonra isə CS registrləri yüklənir. RET əm­rində gös­tərilən məcburi olmayan parametr, prose­dur­dan qayıtma pro­sesində stekdən götürülən elementlərin sayıdır. Elementin ölçüsü SEGMENT-USE16 və ya USE32 direktivlərinə görə müəyyənləşir. Əgər USE16 göstərilibsə, bu ədəd baytlarla, USE32 –isə sözlərlə hesablanır.

Misal 1.
; NEAR atributlu  prosedurun çağırılması 
cod_seg SEGMENT
               ASSUME CS: cod_seg 
main PROC
…
         CALL aux
…
         MOV AX,4C00h
         INT 21h              ; idarəni ƏS  qaytarmlması
main ENDP
aux  PROC NEAR
…
          RET
aux  ENDP
cod_seg ENDS

Misal 2.
; FAR atributlu  prosedurun çağrılması 
cod1  SEGMENT
          ASSUME CS:cod1
main PROC NEAR
…
          CALL  aux
…
          RET
main  ENDP
cod2  SEGMENT
          ASSUME CS:cod2
aux  PROC  FAR
…
          RET
AUX  ENDP
cod2 ENDS

Prosedurun təşkilinə aid aşağıdakı proqramı nəzərdən keçirək. Tutaq ki, bizə A, B və C vektorları verilmişdir. Hər bir vektorun elementlərinin hasilini tapmaq tələb olunur.

MASM 
MODEL SMALL
.STACK 100h
.DATA
mas_a           dw 2,2,2,2,2,2,2,2,2,2
mas_b           dw 1,2,2,2,2,2,2,2,2,2
mas_c           dw 1,2,2,2,2,2,2,2
vur_a	          dw 1
vur_b		dw 1
vur_c		dw 1
vuruq		db  'has=        $',10,13
.CODE
		EXTRN CON2:FAR
main:
	         push @DATA
       	         pop ds
	         xor dx,dx
       	         xor ax,ax
		lea     ax,mas_b 
		lea     bx, mas_a
		sub    ax,bx
		cwd	
		mov	cx,type mas_a
		div	cx
		mov	cx,ax
		mov	bx,offset mas_a
		call	vur
		mov	vur_a,ax
		call	show
		lea       ax,mas_c 
		lea	bx, mas_b
		sub 	ax,bx
		cwd	
		mov	cx,type mas_b
		div	cx
		mov	cx,ax
		mov	bx,offset mas_b
		call	vur
		mov	vur_b,ax
		call	show
		lea       ax,vur_a 
		lea	bx, mas_c
		sub 	ax,bx
		cwd	
		mov	cx,type mas_c
		div	cx
		mov	cx,ax
		mov	bx,offset mas_c
		call	vur
		mov	vur_c,ax
		call	show
		mov	ah,4ch
		int	21h
show		proc
		lea	bx,vuruq+4
		call	con2
		lea	dx,vuruq
		mov	ah,9
		int	21h
		ret
show		endp
vur		proc
		mov     ax,1
start:  	mov	dx,[bx]
	            imul    dx
		inc	bx
		inc     bx
		loop    start
		ret
vur		endp
		end main