Menu

Daxil olun Qeydiyyat

Assembler x86 Linux (64 bit)

Dəyişənlər

Dəyişənlər

Əvvəlki Dəyişənlər proqramın .data hissəsində elan olunur. Dəyişənlərdən hər hansı məlumat saxlamaq üçün istifadə olunur. Assembler dilində dəyişən elan etmək üçün aşağıdakı sintaksisdən istifadə olunur.


nişan:
.tip ilkin_qiymət

Nişan dəyişənin adını bildirir. tip isə dəyişənin yaddaşda neçə bayt yer tutduğunu göstərir. Qeyd edim ki, assembler dilində yüksək səviyyəli dillərdə olduğu kimi, tam tipi, həqiqi tipi, və s. tiplər xarakteristik deyil. Tip deyərkən, əsasən yaddaşda tutulan yerin ölçüsü başa düşülür. Ən geniş istifadə olunan tiplər aşağıdakılardır: byteintlong və asciibyte və ascii tiplər bir bayt, int və long isə, uyğun olaraq 2 və 4 bayt qədər yer tutur. ascii tipindən Simvol tipli məlumatları yerləşdirmək üçün istifadə olunur.

Misal üçün, dey1 və dey2 adlı iki dəyişən elan etmək istəsək, aşağıdakı kimi yazmalıyıq:


dey1:
.long

dey2:
.long

Bu zaman yaddaşda dey1 və dey2 adlı, hər biri 4 bayt yer tutan iki dəyişən elan etmiş oluruq.

Əgər elan zamanı dəyişənlərə ilkin qiymət mənimsətmək istəsək, onda bu qiyməti tipdən sonra qeyd etməliyik. Aşağıdakı kimi:


dey1:
.long 34

Bu zaman artıq dey1 dəyişəninin ilkin qiyməti 34 olar.

 

Cərgələrin elan olunması

Yüksək səviyyəli dillərdə olduğu kimi, assembler dilində də cərgələrdən (massivlər) istifadə etmək mümkündür. Bunun üçün adi dəyişənlər elan etdiyimiz qaydadan istifadə olunur, sadəcə olaraq, bu zaman cərgənin elementləri qeyd edilərək, vergüllə ayrılır. Misal üçün, byte tipindən olan 5 elementli f cərgəsi elan etmək istəsək, onda aşağıdakı kimi yazmaq lazımdır.


f:
.byte 1,3,45,6,7

Bu zaman biz cərgənin elementlərinə ilkin qiymətlər mənimsətmiş olduq.

 

Sətirlərin elan olunması

Assembler dilində sətir elan etmək istəsək, onda yenə də, adi dəyişən elan etmə yolundan istifadə edəcəyik və tip olaraq ascii seçəcəyik. İlkin qiymət olaraq isə, cütdırnaq arasında elan etmək istədiyimiz sətri yerləşdirəcəyik, misal üçün, aşağıdakı kimi:


set:
.ascii "Salam dünya"

Bu qayda ilə biz "Salam dünya" sətrini elan etmiş oluruq.

 

Dəyişənlərin qiymətlərinə müraciət

Gəlin, assembler dilində dəyişənlərə aid bir neçə proqram nümunəsinə baxaq.

proq3.s-də biz iki ədədin cəmini hesabladıq. Ədədlərin qiymətlərini registrlərdə yerləşdirdik. İndi artıq biz fiziki yaddaşa müraciət edə bilərik. Gəlin, eyni proqramı dəyişənlərdən istifadə etməklə tərtib edək.

İki ədədin cəmi proqramı (proq4.s):


#pro14.s

.data

eded1:
.long 45

eded2:
.long 34

.text
.globl _start
.type _start,@function

_start:

movl eded1, %eax
movl eded2, %ebx

addl %eax, %ebx

movl $1, %eax
int $0x80

Proqramı kompilyasiya və icra edək:


[user@unix progs_as]$ 
[user@unix progs_as]$ as proq4.s -o proq4.o
[user@unix progs_as]$ ld proq4.o -o proq4
[user@unix progs_as]$ ./proq4
[user@unix progs_as]$ echo $?
79
[user@unix progs_as]$ 
[user@unix progs_as]$ 

jmp instruksiyası

jmp instruksiyası (hoppanmaq) proqramın icra istiqamətini bir yerdən başqa yerə yönləndirmək üçün istifadə olunur. Əsasən cmp instruksiyası ilə birlikdə istifadə olunur. Yəni müqayisənin nəticəsindən asılı olaraq proqramın icrasını bu və ya digər yerdən davam etdirmək.

jmp instruksiyasının sintaksisi aşağıdakı kimidir:

jmp mövqe

Bu zaman icraolunma artıq "mövqe" adlı yerə sıçrayır.

Sadə proqrama baxaq.


# proq6.s

.text
.globl _start
.type _start,@function

_start:

movl $1, %ecx
movl $5, %edx
addl %ecx, %edx

movl $6, %ebx 

addl %edx, %ebx

son:
movl $1, %eax
int $0x80

Bu proqramda biz _start-dan əlavə son nişanını tərtib etmişik. Nişanları yuxarıda qeyd elədiyimiz kimi, proqramın məlumat və kod hissəsinin istənilən yerində elan edə bilərik. Proqram _start-dan başlayaraq, aşağı doğru yerləşmiş instruksiyaları ardıcıl icra edir. Proqramı icra eləsək, nəticə olaraq 12 alarıq. İndi isə, proqramda jmp instruksiyasından istifadə edək.


# proq6.s

.text
.globl _start
.type _start,@function

_start:

movl $1, %ecx
movl $5, %edx
addl %ecx, %edx

movl $6, %ebx 
jmp son

addl %edx, %ebx

son:
movl $1, %eax
int $0x80

Əgər bu proqramı icra eləsək, onda cavab olaraq 6 qiymətini alarıq. Səbəb isə odur ki, movl $6, %ebx instruksiyasından sonra jmp son instruksiyası icra olunur. Nəticədə addl %edx, %ebx instruksiyası icra olunmadan son nişanına keçid baş verir.

 

cmp instruksiyası

Məlumatların qiymətlərini müqayisə etmək üçün CPU cmp instruksiyasından istifadə edir. cmp instruksiyasının sintaksisi aşağıdakı kimidir:

cmp arq1, arq2

arq1 ilə arq2-in qiyməti yoxlanılır və nəticə flags registrində qeydə alınır. Müqayisənin nəticəsindən asılı olaraq, bu və ya digər əməliyyatı icra etmək üçün

cmp instruksiyasından sonra şərti keçid instruksiyalarından istifadə etməliyik.

Şərti keçid instruksiyaları aşağıdakılardır:

jg, jge, jl, jle, je, jne.

(jump great, jump great equal, jump less, jump less equal, jump equal, jump not equal)

Bu keçid instruksiyaları iki kəmiyyətin müqayisəsinin bütün mümkün nəticələrini uyğun olaraq, aşağıdakı kimi nəzərə alır: keç əgər ikinci arqument birincidən böyükdürsə, böyük bərabərdirsə, kiçikdirsə, kiçik bərabərdirsə, bərabərdirsə, fərqlidirsə.

Proqram nümunəsi: İki ədədin böyüyünü tapan proqram tərtib edək.


#prog7.s


.data

eded1:
.long 110

eded2:
.long 15

.text

.globl _start
.type _start, @function


_start:

#eded1-i eax-ə yaz

movl eded1, %eax
#eded2-ni ebx-ə yaz

movl eded2, %ebx

#ədədləri müqayisə et, əgər ikinci birincidən böyükdürsə

#son-a keç, çünki artıq böyük ədəd ebx-dədir

cmpl %eax, %ebx
jg son

#birinci böyükdür, onu ebx-ə köçür

movl %eax, %ebx

son:
movl $1, %eax
int $0x80

Proqramın izahı:

Biz əvvəlcə eded1 və eded2-nin qiymətlərini uyğun olaraq %eax və %ebx registrlərinə köçürdük. Daha sonra, cmp vasitəsilə bu qiymətləri müqayisə etdik. Əgər %ebx %eax-dən böyük olarsa, bu zamanjg instruksiyası son-a keçəcək, əks halda - (%eax > %ebx) olarsa, proqramın icrası növbəti instruksiyadan davam edir. movl %eax, %ebx. Böyük qiymət %ebx-ə yazılır. Proqram sona çatır.

Tapşırıq:

1. eded1 və eded2-yə (0-255 arası) müxtəlif qiymətlər verməklə proqramı test edib necə işlədiyin yoxlayın.


Bizi dəstəkləyənlər