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
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 #.
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
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
Pozivi I/O rutina se vre standardnom CALL instrukcijom koja je pandan pozivu funkcije u
viem programskom jeziku.
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;
}
%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.
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
%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