You are on page 1of 8

Arhitektura raunara 1

ASEMBLER - 3. termin
1. Kontrolne strukture
Jezici visokog nivoa sadre strukture za kontrolu toka koje su takoe visokog nivoa, npr. if i while
sa preduslovom i postuslovom. Asembler ne omoguava tako kompleksne strukture. Umesto
toga, koristi se nepopularni goto za itavu kontrolu toka programa.
Ako se goto koristi na neodgovarajui nain, svaki program !pa i asemblerski" postaje neitak i
teak za odravanje. Uprkos tome, kori#enjem pravila strukturiranog programiranja, moe se
postii da ak i asemblerski kod bude strukturiran.
2. Poreenja
$ontrolne strukture odluuju #ta da rade bazirajui se na poreenju podataka. U asembleru, rezultat
tog poreenja se uva u %&A'( registru. )*+), procesori koriste -./ instrukciju za izvoenje
poreenja, dok se %&A'( registar menja u skladu sa rezultatom. -./ instrukcija je, u stvari, (U0
!oduzimanje drugog od prvog operanda" , s tim #to se rezultat oduzimanja nigde ne uva.
1a neoznaene cele brojeve, dve zastavice !bita u %&A'( registru" su bitne, i to2 1% !zero flag 3
nula" i -% !carry flag 3 prenos". 1% se postavlja na 4 ako je rezultat operacije razlike *. -% se u
operaciji razlike koristi kada doe do pozajmice. 5a primer2
cmp vleft, vright
Dakle, izraunava se razlika vleft - vright i FLAGS registar se postavlja prema rezultatu. Ako je
razlika 0, tj. vleft=vright, tada se ZF postavlja na 1, dok je CF nula (nema pozajmice). Ako je
vleft>vright, i ZF i CF su nule. Ako je vleft<vright, tada je ZF=0, a CF=1 (dolo je do pozajmice).
Ne treba zaboraviti da i druge instrukcije menjaju FLAGS registar, a ne samo CMP! Poreenje
oznaenih brojeva je neto komplikovanije, pa na ovom mestu nee biti diskutovano.
3. Instrukcije grananja
Instrukcije grananja slue za transfer izvravanja na bilo koju taku unutar programa. Drugim
reima, ove instrukcije igraju ulogu kao goto u nekim programskim jezicima. Postoje dve vrste ovih
instrukcija - uslovne i bezuslovne. Bezuslovna instrukcija je be kao goto, do skoka dolazi uvek.
Uslovne instrukcije grananja mogu, ali ne moraju da izvre grananje, zavisno od stanja FLAGS
registra. Ako do grananja ne doe, kontrola se daje prvoj sledeoj instrukciji.
Instrukcija bezuslovnog skoka je JMP. Njen jedini argument je labela instrukcije na koju se skae.
Labelu asembler i linker zamenjuju konkretnom memorijskom adresom. Vano je napomenuti da
instrukcija odmah posle JMP nee biti nikad izvrena, osim ako se neka druga instrukcija grana na
nju.
Validne labele u kodnom segmentu (.text) se definiu svojim nazivom i dvotakom, nakon ega sledi
instrukcija, kao npr:
while_granica: mov eax,[broj]
Neke od instrukcija uslovnog grananja date su u sledeoj tabeli. Kao svoj operand sve one uzimaju
labelu, kao i JMP.
JZ skok ako je ZF=1, zero, nula
JNZ skok ako je ZF=0
JO skok ako je ZF=1, overflow, izlaz iz opsega
JNO skok ako je ZF=0
JS skok ako je ZF=1, sign, znak
JNS skok ako je ZF=0
JC skok ako je ZF=1, carry, prenos
JNC skok ako je ZF=0
JP skok ako je ZF=1, parity, parnost niih 8 bita
JNP skok ako je ZF=0
Sledei C-ovski pseudo kod:
if ( EAX == 0
E!X = "#
el$e
E!X = %#
u asembleru moe da se napie kao:
cmp eax, 0 # po$tavljanje &a$tavica ('(=" a)o eax*0=0
j& then_blo) # a)o je '( $etovan, $)oci na then_blo)
mov ebx, % # E+,E -eo .(*a
jmp next # pre$)oci /0E1 -eo
then_blo):
mov ebx, " # /0E1 -eo .(*a
next:
Meutim, ostala poreenja, npr. <=, >= nije tako lako izvesti koristei samo instrukcije iz tabele.
Problem je to mora da se vodi rauna o nekoliko zastavica istovremeno.
Na sreu, procesori tipa 80x86 poseduju instrukcije koje omoguavaju mnogo korisniki
orijentisanije grananje. Te instrukcije, i to samo za neoznane cele brojeve kao operande date su u
sledeoj tabeli:
JE skae ako vleft = vright
JNE skae ako vleft != vright
JB, JNAE skae ako vleft < vright
JBE, JNA skae ako vleft <= vright
JA, JNBE skae ako vleft > vright
JAE, JNB skae ako vleft >= vright
Recimo, JB i JNAE su instrukcije sinonimi jer je:
xynot xy
Evo kako bi se u asembler preveo sledei C kod:
22 3 )o-
if ( EAX 4= 5
E!X = "#
el$e
E!X = %#
# a$embler$)i )o-
cmp eax, 5
jae then_blo)
mov ebx, %
jmp next
then_blo):
mov ebx, "
next:
4. Prevoenje standardnih kontrolnih struktura
Ova sekcija data je kao pomo programeru kod prevoenja standardnih struktura kontrole toka iz
viih programskih jezika u asemblerski kod.
4.1 If klauzule
Sledei pseudo kod:
if ( 6$lov
then blo) #
el$e
el$e blo) #
moe se implementirati ovako:
# )o- &a $etovanje (+A7 &a$tavica
jxx el$e_blo) # jxx $e po$tavlja ta)o -a je if 6$lov fal$e8
# )o- then blo)a
jmp en-if
el$e_blo):
# )o- el$e blo)a
en-if:
U sluaju da nema else bloka, instrukcija uslovnog grananja skae na endif:
# )o- &a $etovanje (+A7 &a$tavica
jxx en-if # jxx $e po$tavlja ta)o -a je if 6$lov fal$e8
# )o- then blo)a
en-if:
4.2 While petlje
Opta forma while petlje je:
while ( 6$lov 9
telo petlje#
:
to se u asembleru implementira ovako:
while:
# )o- &a $etovanje (+A7 &a$tavica
jxx en-while # i&abrati xx ta)o -a je 6$lov==fal$e
# telo petlje
jmp while
en-while:
4.3 Do-while petlje
Kod do-while petlje uslov se testira na kraju:
-o 9
telo petlje#
: while ( 6$lov #
to u prevedenom obliku daje:
-o:
# telo petlje
# )o- &a $etovanje (+A7 &a$tavica
jxx -o # i&abrati xx ta)o -a je 6$lov==tr6e
4.4 For petlje
80x86 poseduje nekoliko instrukcija za implementaciju for petlji. Najpoznatija je instrukcija LOOP
koja za broja korsiti ECX registar koji dekrementira, pa ako je ECX!=0 skae na labelu koja se
navodi kao argument.
Sledei pseudo kod:
$6ma = 0#
for ( i ="0# i 40# i ;;
$6ma <= i#
bi se u asembler preveo ovako:
mov eax,0 # eax je $6ma
mov ecx, "0 # ecx je i
loop_$tart:
a-- eax, ecx
loop loop_$tart
5. Primer: Odreivanje da li je broj prost
#
# fajl: pro$t"=a$m
# >rogram )oji i$pi$6je -a li je 6ne$eni broj pro$t
#
# ?a bi $e napravio i&vr$ni fajl:
# na$m *f elf pro$t"=a$m
# gcc *m@% *o pro$t" pro$t"=o -river=c a$m_io=o
#
# >rogram ra-i i$to )ao $le-eci 3 program:
#Aincl6-e B$t-io=h4
#
#int main(
#9
# 6n$igne- int broj#
# 6n$igne- int cinilac#
#
# printf (CDne$i broj : C#
# $canf(CE6C, Fbroj#
#
# cinilac = %#
# while ( cinilac B broj FF brojEcinilac 8= 0
# cinilac <= "#
#
# if (broj==cinilac
# printf(C!roj je pro$tGnC#
# el$e
# printf(C!roj nije pro$tGnC#
#
# ret6rn 0#
#:
#
#
Eincl6-e Ca$m_io=incC
$egment =-ata
por6)a -b CDne$i broj: C, 0
por6)a_nije -b C!roj nije pro$tC,0
por6)a_je$te -b C!roj je pro$tC,0
$egment =b$$
broj re$- " # broj )oji $e i$pit6je

$egment =text
global a$m_main
a$m_main:
enter 0,0 # r6tina &a inicijali&acij6
p6$ha
#Hv-e pocinje )ori$tan )o-
mov eax, por6)a
call print_$tring

call rea-_int # $canf(CE6C, Fbroj#
mov [broj], eax
mov ebx, % # 6 regi$tr6 ebx $e c6va cinilac = %#
while_cinilac:
cmp ebx, [broj]
jnb en-_while_cinilac # if 8(cinilac B broj
mov eax,[broj]
mov e-x,0
-iv ebx # e-x = e-x:eax E ebx
cmp e-x, 0
je en-_while_cinilac # if 8(broj E cinilac 8= 0
inc ebx # cinilac<<#
jmp while_cinilac
en-_while_cinilac:
cmp [broj], ebx
je then_blo) # if (broj==cinilac i-i na then_blo)
mov eax, por6)a_nije # printf(C!roj nije pro$t=GnC
call print_$tring
call print_nl
jmp en-_if
then_blo):
mov eax, por6)a_je$te # printf(C!roj je pro$t=GnC
call print_$tring
call print_nl
en-_if:
popa
mov eax, 0 # vrati $e na&a- 6 3
leave
ret
6. Primer: Nalaenje prostih brojeva manjih od N
Sledei primer pokazuje kako se jednostavan primer dat u programskom jeziku C u celosti prevodi u
asembler. Zadatak je da se pronau i odtampaju svi prosti brojevi manji od broja koji se unosi sa
tastature.
#
# fajl: pro$t=a$m
# >rogram )oji i$pi$6je pro$te brojeve manje o- 6netog broja
#
# ?a bi $e napravio i&vr$ni fajl:
# na$m *f elf pro$t=a$m
# gcc *m@% *o pro$t pro$t=o -river=c a$m_io=o
#
# >rogram ra-i i$to )ao $le-eci 3 program:
#Aincl6-e B$t-io=h4
#
#int main(
#9
# 6n$igne- int broj#
# 6n$igne- int cinilac#
# 6n$igne- int granica#
#
# printf (C>rona-ji pro$te brojeve $ve -o : C#
# $canf(CE6C, Fgranica#
# broj = %# 22 >ocinje $e o- %
#
# while ( broj B= granica
# 9
# cinilac = %#
# while ( cinilac B broj FF brojEcinilac 8= 0
# cinilac <= "#
# if ( broj == cinilac
# printf (CE-GnC, broj#
# broj <= "#
# :
#
# ret6rn 0#
#:
#
Eincl6-e Ca$m_io=incC
$egment =-ata
por6)a -b C>rona-ji pro$te brojeve $ve -o: C, 0
$egment =b$$
granica re$- " # granica )oj6 6no$i )ori$ni)
broj re$- " # te)6ci broj )oji $e i$pit6je

$egment =text
global a$m_main
a$m_main:
enter 0,0 # r6tina &a inicijali&acij6
p6$ha
# Hv-e pocinje )ori$tan )o-
mov eax, por6)a
call print_$tring

call rea-_int # $canf(CE6C, Fpor6)a #
mov [granica], eax
mov -wor- [broj], % # broj = %#
while_granica: # while ( broj B= granica
mov eax,[broj]
cmp eax, [granica]
jnbe en-_while_granica # $)ace a)o je broj 4 granica
mov ebx, % # 6 regi$tr6 ebx $e c6va cinilac = %#
while_cinilac:
cmp ebx, [broj]
jnb en-_while_cinilac # if 8(cinilac B broj
mov eax,[broj]
mov e-x,0
-iv ebx # e-x = e-x:eax E ebx
cmp e-x, 0
je en-_while_cinilac # if 8(broj E cinilac 8= 0
inc ebx # cinilac<<#
jmp while_cinilac
en-_while_cinilac:
cmp [broj], ebx
jne en-_if # if 8(broj==cinilac i&a-ji i& if*a
mov eax,[broj] # printf(CE6GnC
call print_int
call print_nl
en-_if:
a-- -wor- [broj]," # broj<="
jmp while_granica
en-_while_granica:
popa
mov eax, 0 # vrati $e na&a- 6 3
leave
ret
--------------------------
Deljenje
Instrukcija DIV je instrukcija celobrojnog deljenja. Deljenik se smeta u kombinaciju registara
EDX:EAX (64 bita ukupno), nakon ega se deli operandom instrukcije DIV. Rezultat se smeta u
EAX, dok se ostatak u EDX.
Mnoenje
Slino tome, celobrojno mnoenje 32-bitnih celobrojnih vredosti se obavlja instrukcijom
m6l $o6rce
gde se 32-bitna vrednost na koju pokazuje source mnoi sadrajem registra EAX, a 64-bitni rezultat
se smeta u kombinaciju registara EDX:EAX.

You might also like