Anda di halaman 1dari 8

Arhitektura raunara 1

ASEMBLER - 2. termin

1. Mainski jezik
Svaki tip CPU-a razume iskljuivo svoj sopstveni mainski jezik. Instrukcije u mainskom jeziku
su pohranjene kao bajtovi unutar memorije. Svaka instrukcija ima svoj jedinstveni numeriki kod,
tzv. operacioni kod ili opcode. Opcode se uvek nalazi na poetku instrukcije. Mnoge instrukcije
nakon opcode-a sadre i podatke.
Veoma je teko programirati direktno u mainskom jeziku. Sledi primer instrukcije koja
izraunava zbir EAX i EBX registara i rezultat smeta u EAX registar:
03C3

Na sreu, postoji tzv. asembler koji tekstualne instrukcije prevodi direktno u mainski jezik.
Jedan od takvih programa je i NASM (Netwide ASseMbler).

2. Asemblerski jezik
Asemblerski program se pohranjuje kao tekst, tj. kao bilo kakav program napisan u viem
programskom jeziku kao to je C. Svaka asemblerska instrukcija predstavlja po jednu mainsku
instrukciju, dakle postoji 1-1 preslikavanje. Na primer, gornja instrukcija se u asembleru
reprezentuje kao:
addeax,ebx

Dakle, ovde je znaenje instrukcije daleko jasnije nego u mainskom kodu. Opti oblik
instrukcije u asembleru je:
mnemonic operand(s)
Zadatak asemblera je da tekstualni kod prevede u mainski, slino kao to to ine kompajleri
viih programskih jezika. Shodno bliskosti asemblera i mainskog jezika, asembler je dosta
jednostavniji od bilo kog kompajlera.
Druga vana razlika izmeu asemblera i viih programskih jezika je u tome to asemblerski
programi zavise od arhitekture CPU-a i nisu portabilni.
U daljem toku vebi bie korien NASM asembler na platformi Debian Linux i386 32bit. Drugi
popularni asembleri su MASM (Microsoft Assembler) i TASM (Turbo Assembler). Postoje izvesne
razlike u sintaksi meu pomenutim asemblerima.

3. Instrukcijski operandi
Asemblerske instrukcije imaju razliit broj i tip operanada, meutim, svaka instrukcija sama po
sebi ima fiksni broj operanada (od 0 do 3), koji mogu biti sledeih tipova:
registar - ovi operandi referenciraju direktno CPU registre
memorija - referenciraju podatke u memoriji. Adrese podataka mogu biti konstante zadate u
kodu ili zadate vrednostima u registrima. Adrese su uvek dodatak (offset) koji se zadaje od
poetka segmenta.
neposredni - fiksne vrednosti zadate unutar same instrukcije. uvaju se u kodnom
segmentu (.text), a ne u segmentu podataka (.data, .bss).
implicitni - operandi koji nisu prikazani na eksplicitan nain. Na primer, instrukcija inc
dodaje jedinicu registru ili podatku u memoriji. Jedinica je implicirana.

4. Osnovne instrukcije
Najosnovnija asemblerska instrukcija je instrukcija MOV. Ona pomera podatak sa jedne lokacije
na drugu (poput operatora dodele u viem jeziku; :=, =). Uzima dva operanda:
movdest,src

Podatak specificiranu src kopira se u dest. Restrikcija je da ne mogu oba operanda biti podaci
u memoriji, ve se ta vrsta dodele mora vriti preko registra.
Druga restrikcije se odnosi na veliinu operanada, tj. uslov da operandi moraju biti iste duine.
Ne moe se vrednost iz AX registra (16 bita) smestiti u BL registar (8 bita).
Evo primera:
moveax,3 ;smetanjebroja3uEAXregistar,3jeneposredanoperand
movbx,ax ;smetanjevrednostiuAXregistruuBXregistar

ADD instrukcija slui za sabiranje celih brojeva:


addeax,4 ;eax=eax+4
addal,ah ;al=al+ah

SUB slui za oduzimanje celih brojeva:


subbx,10 ;ebx=ebx10
subebx,edi ;ebx=ebxedi

INC i DEC instrukcije slue za inkrementiranje, odn. dekrementiranje za 1:


incecx ;ecx++
decdl ;dl

5. Direktive
Direktive se tiu samog asemblera, a ne CPU-a. U optem sluaju se koriste da instruiu
asembler da uini neku akciju ili da ga o neemu informiu. Uobiajene namene direktiva su:
definisanje konstanti
definisanje memorijskih resursa za smetaj podataka
grupisanje memorije u segmente
(uslovno) ukljuivanje izvornog (source) koda
NASM kod prolazi kroz pretprocesor potpuno isto kao C, pri emu ima i veliki broj slinih
instrukcija kao C. Jedino to kod NASM-a te instrukcije poinju znakom % umesto #.

5.1 equ direktiva


Equ direktiva se koristi za definisanje simbola. Simboli su imenovane konstante u asemblerskom
programu. Format instrukcije je:
simbol equ vrednost
Simboli se kasnije ne mogu redefinisati.

5.2 %define direktiva


Ova direktiva ima jasnu analogiju sa #define direktivom u C-u. I nain upotrebe je skoro
identian, tj. upotrebljava se za definisanje konstanti i makroa:
%defineSIZE100
moveax,SIZE

Makroi su efikasniji od simbola jer se mogu redefinisati.

5.3 Direktive podataka (data directives)


Direktive podataka se koriste u segmentu podataka, i to za rezervaciju prostora u memoriji za
podatke. Prvi metod definie samo prostor za njihov smetaj, dok drugi nain rezervie prostor i
dodeljuje inicijalnu vrednost.
Prvi metod koristi neku od RESX direktiva, gde se X zamenjuje slovom koje definie veliinu
objekta (objekata). Tabela prikazuje listu dozvoljenih vrednosti:
Jedinica Slovo
byte B
word W
double word D
quad word Q
ten bytes T
Drugi metod (onaj koji inicijalizuje vrednost) koristi jednu od DX direktiva, gde X ima isto
znaenje kao kod RESX.
Uobiajeno je da se memorijske lokacije obeleavaju labelama. Evo nekoliko primera:

Vano je napomenuti da su dozvoljeni i jednostruki i dvostruki navodnici i da se tretiraju na


potpuno isti nain. Uzastopni podaci se smetaju jedan za drugim i u memoriji raunara, tj. L2 se u
memoriji smeta odmah posle L1.
Takoe se mogu definisati i memorijske sekvence, to je jako vano pri definiciji nizova i
stringova:

DD direktiva moe posluiti kako za definisanje celobrojnih konstanti, tako i za definisanje


konstanti u pokretnom zarezu jednostruke preciznosti (float u C-u). Nasuprot tome, DQ se koristi
samo za brojeve u pokretnom zarezu dvostruke preciznosti.
Za dugake sekvence, NASM direktiva TIMES je veoma korisna:

Treba naglasiti da se labele mogu koristiti u svrhu referisanja podataka u kodu. Postoje dva
naina za to:
Ako se koristi ista labela, ona se odnosi na adresu podatka u memoriji
Ako se upotrebi labela u uglastim zagradama ([]), interpretira se kao podatak na toj adresi.
Drugim reima, labela je neka vrsta pokazivaa na podatke u memoriji, dok je operator []
dereferencira na isti nain kako to ini * u C-u. U 32-bitnom modu, adresa je 32-bitna. Evo
nekoliko primera:

Poslednja linija pokazuje joe jednu vanu osobinu asemblera; ASEMBLER NE VODI
RAUNA O TIPU PODATKA NA KOJI SE LABELA REFERENCIRA. Na programeru je da o
tome vodi rauna. Zato je asembler podloniji grekama od C-a.
Primera radi, sledea instrukcija nije korektna:
mov[L6],1 ;smestiti1naadresuL6

to nije u redu? Instrukcija proizvodi greku operationsizenotspecified zato


to ne zna kako da interpretira 1; kao bajt, re ili duplu re. Da bi se ovo ispravilo, dodaje se
specifikator veliine:
movdword[L6],1 ;smestiti1naadresuL6

6. Ulaz i izlaz
Ulazno/izlazne aktivnosti su, po prirodi stvari, veoma zavisne od sistema. Ove rutine zahtevaju
interakciju sa sistemskim hardverom. Jezici vieg nivoa, kao to je C, isporuuju biblioteku
standardnih rutina koje omoguavaju vrlo jednostavan i uniforman interfejs za I/O. Asembler nema
nikakvu standardnu biblioteku za ovu svrhu.
Vrlo je uobiajeno da se asemblerske rutine meaju sa C-ovskim. Jedna od prednosti ovog
pristupa je da tada asembler moe da poziva C bibloteku za I/O rutine. Bez ulaenja u pravila
pozivanja C-a iz asemblera i obrnuto, za I/O koristie se nezavisna biblioteka koju daje autor knjige
PC Assembly Language, pod nazivom asm_io. Da bi se pozivale I/O rutine, mora se ukljuiti fajl sa
informacijama o njima:
%includeasm_io.inc

Tabela pomenutih rutina sa objanjenjem sledi:


print_int tampa na ekran vrednost celog broja u registru EAX
print_char tampa karakter ija je ASCII vrednost smetena u AL registar
print_string tampa string ija se adresa nalazi u EAX. String mora da bude
terminiran nulom, kao u C-u.
print_nl prelazak na novu liniju
read_int ita celi broj sa tastature i smeta ga u EAX registar
read_char ita jedan karakter i smeta njegov ASCII kod u EAX.

Pozivi I/O rutina se vre standardnom CALL instrukcijom koja je pandan pozivu funkcije u
viem programskom jeziku.

7. Ispravljanje greaka (debugging)


Biblioteka asm_io sadri i neke korisne rutine za ispravljanje greaka. Ove rutine daju
informacije o stanju bez modifikacije zateenog stanja. To su, u stvari, makroi koji ispisuju
vrednosti u registrima, memoriji, steku i i matematikom koprocesoru:
dump_regs tampa vrednosti u registrima u heksadekadnom zapisu. Takoe tampa
vrednosti bitova u FLAG registru. Na primer, ako je ZF=1, tampa se
ZF, a ako je ZF=0 ne tampa se nita. Uzima jedan celobrojni argument
koji slui samo za identifikaciju
dump_mem tampa vrednosti u regionu memorije u heksadekadnom i ASCII zapisu.
Uzima tri argumenta, pri emu je prvi identifikator (kao u dump_regs),
drugi je adresa (labela), a poslednji broj 16-bitnih paragrafa za prikaz.
dump_stack tampa vrednosti na CPU steku. Jedinica organizacije steka je dupla re
(double word). Uzima tri argumenta; prvi je identifikator, drugi je broj
duplih rei za prikaz ispod adrese u EBP registru, a trei broj duplih rei
iznad adrese u EBP registru.
dump_math tampa vrednosti u registrima matematikog koprocesora. Jedini
argument je identifikator

8. Prvi program
Danas je neuobiajeno razvijati samostalan program napisan u potpunosti u asembleru. Asembler
se koristi za rutine koje su kritine za brzinu. Zato e i asemblerski programi koji slede potovati
ovu politiku.
Dakle, asemblerski program e se pozivati iz jednostavnog C programa ija je svrha iskljuivo
pozivanje glavne asemblerske rutine. Vie je prednosti ovakvog naina upotrebe. Prvo, C e prvo
korektno startovati program u zatienom (protected) modu, pri emu e svi segmenti i
odgovarajui registri biti ispravno inicijalizovani. Drugo, i vanije, rutine C biblioteke e moi da
se pozovu iz asemblera. Biblioteka asm_io koristi ba ovu prednost, tj. standardne C funkcije kao
to je printf. Evo jednostavnog C drajverskog programa:
intmain()
{
intret_status;
ret_status=asm_main();
returnret_status;
}

A evo i jednostavnog asemblerskog programa first.asm:


;
;file:first.asm
;Prviasemblerskiprogram.Ucitavadvabrojaiizracunavaistampazbir
;
;Zaprevodjenjeprograma:
;KoristeciLinuxigcc:
;nasmfelffirst.asm
;gccm32ofirstfirst.odriver.casm_io.o
;

%include"asm_io.inc"
;
;inicijalizovanipodacisestavljajuu.datasegment
;
segment.data
;
;Ovosustringovizaporuke
;
prompt1db"Unesibroj:",0;nezaboravi'0'terminator
prompt2db"Unesidrugibroj:",0
outmsg1db"Uneliste",0
outmsg2db"i",0
outmsg3db",njihovzbirje",0

;
;neinicijalizovanipodacisestavljajuu.bsssegment
;
segment.bss
;
;Ovosuduplereci(doublewords)gdeseucitavajudvabroja
;
input1resd1
input2resd1

;
;kodsenalaziu.textsegmentu
;
segment.text
globalasm_main
asm_main:
enter0,0;ulaznarutina
pusha

moveax,prompt1;stampanjepitanja
callprint_string

callread_int;ucitavanjebroja
mov[input1],eax;snimanjenaadresuinput1

moveax,prompt2;stampanjepitanja
callprint_string

callread_int;ucitavanjebroja
mov[input2],eax;snimanjenaadresuinput2

moveax,[input1];eax=dwordnaadresiinput1
addeax,[input2];eax+=dwordnaadresiinput2
movebx,eax;ebx=eax
dump_regs1;odstampajvrednostiuregistrima
dump_mem2,outmsg1,1;dodstampajvrednostiumemoriji
;
;stampanjeizlazneporukeuserijikoraka
;
moveax,outmsg1
callprint_string;stmpanjeprveporuke
moveax,[input1]
callprint_int;stampanjeinput1
moveax,outmsg2
callprint_string;stampanjedrugeporuke
moveax,[input2]
callprint_int;stampanjeinput2
moveax,outmsg3
callprint_string;stampanjetreceporuke
moveax,ebx
callprint_int;stampanjezbirakojisenalaziuebx
callprint_nl;stampanjenovelinije

popa
moveax,0;vratiseuCprogram
leave
ret

Kao to se moe videti, u .data segmentu se definiu iskljuivo podaci kojima se dodeljuje
poetna vrednost. U linijama koje slede, definie se nekoliko stringova koji se tampaju pomou C
biblioteke pa moraju biti terminirani null karakterom (ASCII kod 0).
Neinicijalizovani podaci idu u .bss segment. To su podaci koji tek treba da se proitaju sa
tastature.
U .text segmentu nalazi se sam kod, dok global direktiva nareuje asembleru da rutina
asm_main bude globalna kako bi C drajverski program mogao da je pozove. U asembleru, za
razliku od C-a, promenljive podrazumevano imaju interni opseg (scope), dok ih global direktiva
ini eksternim.

8.1 Proces kompajliranja i linkovanja


Da bi se ovaj program kompajlirao, potrebno je prevesti ga u objektni fajl, kao to to ini
kompajler u nekom viem programskom jeziku. Naredba koja izvodi ovu operaciju je:
nasmfelffirst.asm

Linux koristi ELF (Executable and Linkable Format) format objektnih fajlova, pa se takav
argument navodi u komandnoj liniji. Nakon izvoenja komande, dobija se first.o objektni fajl. U
Windowsu je najraireniji OMF format objektnog fajla.
Drajverski program napisan u C-u takoe se mora prevesti, i to standardnom komandom:
gccc[m32]driver.c

Argument -c znai da se kod samo kompajlira, bez pokuaja da se linkuje. Argument -m32 je
obavezan ukoliko se kompajliranje vri na 64-bitnoj maini, jer je mainski kod koji se generie 32-
bitni.
Nakon to su svi kodovi iskompajlirani, tj. prevedeni u objektne fajlove (first.o, driver.o i
asm_io.o), moe se pristupiti linkovanju iji je rezultat izvrni program:
gcc[m32]ofirstdriver.ofirst.oasm_io.o

Time je izgradnja programa dovedena do kraja.


8.2 Kostur koda
Sledi kostur koda koji e nadalje biti upotrebljavan za sve asemblerske programe:
;
;file:kostur.asm
;Kosturasemblerskogprograma
;

%include"asm_io.inc"
segment.data
;
;ovdeidupodacikojiseinicijalizuju
;

segment.bss
;
;neinicijalizovanipodacisestavljajuu.bsssegment
;

segment.text
globalasm_main
asm_main:
enter0,0;ulaznarutina
pusha

;
;Uovomdeluidekodkojinestoradi.Nemodifikovatikod
;unutar.textsegmentapreiliposleovogkomentara
;

popa
moveax,0;vratiseuCprogram
leave
ret

Anda mungkin juga menyukai