Title: X86 asembler
1X86 asembler
280386 procesor
- 32-bitna CISC arhitrktura.
- Pretežno dvoadresna mašina.
- Velicina memorijskog adresnog prostora 4GB.
- Adresibilna jedinica bajt.
- Velicina podataka u instrukcijama
- bajt,
- rec (word) dva uzastopna bajta,
- dvostruka rec (double word) cetiri uzastopna
bajta.
3Redosled bajtova podatka u memoriji
- Little-endian viši bajt na višoj adresi.
- Rijeci
- (a) 34 12
- (a1) 56 34
- (a2) 78 56
- Duple rijeci
- (a) 78 56 34 12
4Zdravo svete! (Linux, int) 3
- .intel_syntax noprefix.arch i386.data
1poruka.ascii Zdravo svete!\nkraj_poruke.
equ duzina_poruke, kraj_poruke
poruka.text 1
- .globl _start_startmov ebx, 1 mov ecx,
offset porukalea ecx, porukamov edx,
duzina_porukemov eax, 4int 0x80 2mov
ebx,0mov eax,1int 0x80 2
5Prevodenje, povezivanje i pokretanje
- Asembliranje
- as zdravo_svete.s o zdravo_svete.o
- korišcena opcija -o ltoutput_file_namegt
- Linkovanje (povezivanje)
- ld zdravo_svete.o o zdravo_svete
- korišcena opcija -o ltoutput_file_namegt
- Pokretanje
- ./zdravo_svete
6Prevodenje i povezivanje pomocu gcc
- Asembliranje
- gcc -c -o zdravo_svete.o zdravo_svete.s
- korišcene opcije
- -o ltoutput_file_namegt
- -c Prevedodenje i asembliranje, bez linkovanja
- Linkovanje (povezivanje)
- gcc -o zdravo_svete -nostartfiles zdravo_svete.o
- korišcene opcije
- -o ltoutput_file_namegt
- -nostartfiles Poveži bez standardnih startup
fajlova. - Ili, i prevodenje i povezivanje jednim pozivom
gcc - gcc -o zdravo_svete -nostartfiles zdravo_svete.s
- Druge opcije
- -nodefoultlibs Povezivanje bez standardnih
biblioteka. - -nostdlib Kao nostartfiles nodefaultlibs
- -v Ispisuje komande koje pokrece.
- - Kao prethodno, ali bez izvršavanja komandi.
7Asemblerske naredbe (Intel sintaksa)
- labela mnemonik operandi komentar
- Labela predstavlja adresu na kojoj se nalazi
naredba. - mnemonik je simbolicki zapisana komanda.
- Mogu biti do dva operanda.
- Prvi je uvijek odredište, a nekad i izvorište.
- Drugi je izvorište.
8Transfer podataka
- mov dst, src dst src
- lea dst, src dst offset(src)1
- lds dst, src dsdst src
- les dst, src esdst src
- xchg op1, op2 mijenja vrijednosti u
operandima op1 i op2
9Programski dostupni registri(flat mode,
aplikativni režim)
- Opštenamjenski (32-bitni)
- eax, ebx, ecx, edx, esi i edi.
- Registri za manipulaciju podacima na steku
- esp i ebp.
- Segmentni registri (16-bitni)
- cs, ss, ds, es, fs i gs.
- U flat modu, svi ukazuju na pocetak memorije.
- Registri dostupni samo korišcenjem posebnih
instrukcija - programski brojac eip,
- statusna rijec procesora eflags.
10Preslikavanje logicke u linearnu (flat) adresu
- Logicka adresa
- (Selektor) ofset
- Selektor (16b) segmentni registar
- Ofset adresa iz instrukcije(32bita)
- Selektor pokazuje na deskriptor u okviru
deskriptorske tabele (deo operativnog sistema) - Svi moderni OS podešavaju sadržaj deskriptora
svih segmenata tako da pokazuju na logicku
adresu 0, tako da je programeru dostupan ceo
prostor od 4GB koristeci samo ofset i ne vodeci
racuna o segmentima tzv. Linearni adr. prostor - Po potrebi se može ukljuciti i stranicenje, kada
se logicka adresa preslikava u fizicku adresu.
11Opštenamjenski registri
- Nižih 16 bita registara eax, ebx, ecx i edx se
može koristiti i kao - 16-bitni registar ax, bx, cx i dx
- dva 8-bitna registra
- Npr. ax -gt
- ah viši bajt,
- al niži bajt.
- Imaju i posebne namene
- eax akumulator,
- ebx bazni registar za adresiranje,
- ecx brojacki registar,
- edx pomocni registar za podatke u nekim
instrukcijama, - esi i edi indeksiranje pri adresiranju.
12Registri za rad sa stekom
- esp pokazivac na vrh steka
- pokazuje na zauzetu lokaciju na vrhu steka,
- umanjuje se pre smeštanja podatka,
- uvecava se posle skidanja podatka.
- ebp bazni registar za pristup argumentima
potprograma i lokalnim promenljivim - Radi sa
- Recima (16 bita esp se menja za 2)
- Duplim recima (32 bita esp se menja za 4)
13Rad sa stekom
- push src stavlja na stek src
- pop dst sa steka upisuje u dst
- pushfd cuva eflags na steku
- popfd restaurira eflags sa steka ( u
neprivilegovanom režimu bitovi posle OF
nece se promeniti) - pushf/popf koristi samo donjih 16 bita eflags
- pushad/popad cuvanje svih registara na
steku eax, ecx, edx, ebx, esp, ebp,
esi, edi.
14Statusna rijec procesora
VM RF NT IOPL OF DF IF TF SF
ZF AF PF CF
- CF prenos.
- PF parnost.
- AF pomocni prenos za BCD aritmetiku.
- ZF rezultat nula.
- SF negativan rezultat.
- TF prekid posle svake instrukcije.
- IF maskiranje svih maskirajucih prekida.
- DF smjer za operacije nad stringovima.
- OF prekoracenje.
- IOPL I/O priviledge level
- NT nested task flag
- RF resume flag
- VM virtual 8086 mode
15Nacini adresiranja 1/2
- Neposredno
- mov eax, 10
- add ebx, 20h
- Registarsko direktno (svi registri)
- mov eax, 2
- mov edi, ebx
- mov ebp6, ecx
- Memorijsko direktno
- mov eax, suma
- mov niz6, edx ...
16Nacini adresiranja 2/2
- Registarsko indirektno (svi opšte namene)
- mov ebx, eax
- Registarsko indirektno sa pomerajem
- mov eax88h, 2
- mov nizedx, 2
- Bazno indeksno (adresa se sastoji od dva
registra) - mov ebxedx, eax
- Bazno indeksno sa pomjerajem (kao prethodno plus
pomjeraj) - mov eax, nizebxedi
17Skaliranje indeksa
- Opšti oblik
- ltkonstantagtltbazna_adresagtltfaktorgtltindeksgt
- ltfaktorgt može biti
- 1,
- 2,
- 4.
- mov eax, sumaebx4esi
- mov vrstaedx2eax, bx
18Napomene
- Samo jedan operand u memoriji
- postoji nekoliko izuzetaka.
- Podrazumjevana upotreba segmentnih registara
- cs kod,
- ds podaci, osim ako se u adresnom izrazu
koristi ebp - ss ako se u adresnom izrazu koristi ebp
- Zamjena podrazumjevanog segmentnog registra
- mov ax,dsebp4
- Flat režim samo jedan segment velicine 4GB.
19Sistemski pozivi (Linux)
- Tri nacina
- direktno,
- kroz prekid 0x80,
- kod novijih procesora, instrukcijama SYSENTER i
SYSEXIT, - indirektno, preko funkcija omotaca iz standardne
biblioteke. - int 0x80
- eax 1 exit(int)
- ebx povratna vrijednost programa.
- eax 3 read(int, char, int)
- ebx rucka fajla (0 za standardni ulaz),
- ecx adresa bafera,
- edx velicina bafera u B.
- eax 4 write(int, char, int)
- analogno prethodnom (1 je rucka za standardni
izlaz).
20Zdravo svete! (Linux, int) 3
- .intel_syntax noprefix.arch i386.data
1poruka.ascii Zdravo svete!\nkraj_poruke.
equ duzina_poruke, kraj_poruke
poruka.text 1
- .globl _start_startmov ebx, 1 mov ecx,
offset porukalea ecx, porukamov edx,
duzina_porukemov eax, 4int 0x80 2mov
ebx,0mov eax,1int 0x80 2
21Zdravo svete! (Linux, libc) 1
- .intel_syntax noprefix .arch i386.dataporuka.
asciz "Zdravo svete!\nkraj_poruke .equ
duzina_poruke, kraj_poruke poruka .text .exter
n write.extern exit
- .globl _start _start push duzina_poruke
push offset poruka push 1 call write add esp,
12 write(1,poruka, duzina_poruke) - push 0 call exit exit(0).end
22Prevodenje, povezivanje i pokretanje
- Asembliranje
- as -o p1.o p1.s
- Povezivanje
- ld -o p1 -dynamic-linker /lib/ld-linux.so.2 p1.o
-l c - l c
- ukljucuje biblioteku libc.a1,
- važno navesti biblioteku posle objektnih fajlova
koji je koriste2. - dynamic-linker /lib/ld-linux.so.2
- ukljucuje biblioteku za dinamicko povezivanje.
- Pokretanje
- ./zdravo_svete
23Potprogrami
- Pocinje labelom i opciono
- u redu ispred labele .type ltlabelagt, _at_Function
- za potrebe umetanja informacija za debug
- na pocetku .func ltnazivgt , ltlabelagt1
- na kraju .endfunc
- Završava se instrukcijom za povratak iz
potprograma - ret exp u flat modelu, bliski povratak (samo
offset) - exp broj koji po povratku treba dodati na esp
- Poziv potprograma
- call dst
- near poziv -gt na steku se cuva EIP (u flat režimu
se koristi ovaj pristup) - far poziv -gt na steku se cuvaju CS i EIP
- skace na dst
24Proslijedivanje parametara u registrima i
globalnim promjenljivim
- Prije poziva se upisuje u registar ili globalno
dostupnu memorijsku lokaciju. - IZBEGAVATI, osim ako je primarna brzina.
- U jednom trenutku smije postojati najviše jedan
poziv takve funkcije -gt 1 - Da li je dozvoljena rekurzija?
- Pozivanje u prekidnim rutinama?
- Pozivanje u konkurentnim nitima?
25Proslijedivanje parametara preko steka
- Parametri se prije poziva ostavljaju na steku.
- U funkciji im se pristupa pomocu registra EBP.
- Zato svaka funkcija
- pocinje sapush ebpmov ebp, esp ili
enter 0, 0 1 - završava se samov esp, ebp ili
leave 2pop ebp - Ovako je obezbjedeno da svaki poziv funkcije ima
svoj zapis na steku (prikaz na sledecem slajdu).
26Zapis poziva funkcije
Bliski poziv
Zapis tekuceg poziva neke funkcije
Locm
-4m
...
enter 4m,0
Loc1
-4
EBPstaro
retEIP
4
call naziv_funkcija
Param1
8
Pred poziv funkcije push paramn push param1
...
Paramn
44n
27Instrukcija enter
- enter op1, op2
- op1
- broj bajtova koje je potrebno rezervisati za
lokalne prom. - 16-bitna neposredna konstanta.
- op2
- dubina ugniježdenosti funkcije (0-31),
- govori koliko pokazivaca na prethodne okvire
treba iskopirati u tekuci. - algoritam 1
- push ebp
- mov ebp, esp
- Na stek doda pokazivace na okvirove prethodnih
nivoa (stare vrednososti epb registra) - sub esp, op1
28Konvencije pozivanja potprograma
- Konvencija pozivanja potprograma definiše
- kako se poravnava stek,
- kako se prosleduju parametri,
- ko radi oslobadanje prostora sa steka,
- kako se vraca vrednost,
- koji registri mogu da se koriste u funkciji bez
da se cuvaju. - Konvencije koje se koriste u gcc-u
- cdecl (podrazumjevana)
- stdcall
- fastcall
29cdecl konvencija pozivanja
- Pred poziv funkcije, stek mora biti poravnat na
granicu deljivu sa 16.1 - Argumenti se smeštaju na stek, s desna na levo.
- Prostor na steku oslobada pozivaoc
- izuzetak je skriveni pokazivac, kojeg oslobada
pozvana funkcija. - Vrednost se najcešce vraca u registru
- 1 bajt -gt AL
- 2 bajta -gt AX
- 4 bajta -gt EAX (naredni primjer)
- 8 bajtova -gt EDXEAX
- struktura ili klasa -gt preko skrivenog pokazivaca
2 - Funkcija ne mora da cuva registre eax, ecx i edx
30Razlike stdcall i fastcall u odnosu na stdcall
- stdcall
- pozvani potprogram skida sve argumente sa steka
- fastcall
- prva dva argumenta, ako su celobrojnog tipa,
prosleduju se - prvi u ecx
- drugi u edx
- ostali, kao i oni koji nisu celobrojnog tipa1
prosleduju se preko steka - pozvani potprogram skida sve argumente sa steka
- u slucaju da je promenljiv broj argumenata, na
stek se stavljaju svi.
31Napisati potprogram za sabiranje dva broja
koristeci stdcall i cdecl konvencije 1
- Potprogramstdcallsaberi enter 0, 0 mov
eax, ebp8 add eax, ebp12 leave ret
8 cdecl saberi enter 0, 0 mov eax,
ebp8 add eax, ebp12 leave ret
- Primjer pozivapush broj1push broj2call
saberimov rezultat, eaxpush broj1push
broj2call saberimov rezultat, eaxadd esp, 8
32Napisati potprogram za sabiranje dva broja
?
58
EAX
- push 25
- push 33
- call saberi
- retAdr
- mov rezultat, eax
- saberi
- enter 0, 0
- mov eax, ebp8
- add eax, ebp12
- leave
- ret 8
EBP_old
retAdr
33
33
25
25
33Vracanje vrijednosti preko steka
- typedef struct
- int a, b
- struc
- struc f(int x, int y)
- struc a
- a.a x
- a.b y
- return a 1
-
- void main()
- struc r f(0x1122, 0x3344)
-
- ltfgt
- push ebp
- mov ebp, esp
- sub esp, 0x10 za lokalne promjenljive
- mov eax, 0xcebp eax x
- mov ebp-0x8, eax a.a eax
- mov eax, ebp0x10 eax y
- mov ebp-0x4, eax b.b eax
- mov ecx, ebp0x8 ecx ret_bafer
- mov eax, ebp-0x8 eax a.a
- mov edx, ebp-0x4 edx a.b
- mov ecx, eax ret_bafer.a eax
- mov ecx0x4, edx ret_bafer.b edx
- mov eax, ebp0x8 eax ret_bafer
34Sabiranje i oduzimanje
- add dst, src dstdstsrc
- adc dst, src dstdstsrccf
- sub dst, src dstdst-src
- sbb dst, src dstdst-src-cf
- neg dst dst-dst
- inc dst dstdst1
- dec dst dstdst-1
- cmp src1, src2 setuje flegove na osnovu
src1-src2
35Množenje i dijeljenje
- mul src neoznaceno množenje
- imul src oznaceno množenje
- src (8-bitni) množi sa al i rezultat ostavlja u
ax - src (16-bitni) množi sa ax i rezultat ostavlja u
dxax - src (32-bitni) množi sa eax i rezultat ostavlja u
edxeax - div src neoznaceno dijeljenje
- idiv src oznaceno dijeljenje
- Dijeli ax sa src (8-bitni) i rezultat ostavlja u
al, a ostatak u ah. - Dijeli dxax sa src (16-bitni) i rezultat
ostavlja u ax, a ostatak u dx - Dijeli edxeax sa src (32-bitni) i rezultat
ostavlja u eax, a ostatak u edx - Za množenje postoje i druge forme, sa dva i tri
operanda
36Proširivanje podataka znakom
- cbw proširuje ah sa znakom iz al
- cwde proširuje eax sa znakom iz ax
- cwd proširuje dx sa znakom iz ax
- cdq proširuje edx sa znakom iz eax
37Logicke operacije
- not dst dst dst
- and dst, src dst dst src
- or dst, src dst dst src
- xor dst, src dst dst src
- test op1, op2 setuje flegove na osnovu
op1 op2
38Pomjeranje i rotiranje
- shl dst, cnt pomjeranje logicki lijevo
- sal dst, cnt pomjeranje aritmeticki lijevo
- shr dst, cnt pomjeranje logicki desno
- sar dst, cnt pomjeranje aritmeticki desno
- ror dst, cnt rotiranje desno
- rol dst, cnt rotiranje lijevo
- rcr dst, cnt rotiranje kroz cf desno
- rcl dst, cnt rotiranje kroz cf lijevo
- cnt može biti
- 1,
- neposredna vrijednost ili
- registar cl.
39Primjer
- stanje prije ax0xf00f, CF0, cl2
- shl ax, cl 0xC03C, CF1 (bit koji je ispao)
- sal ax, cl 0xC03C, CF1 (bit koji je ispao)
- shr ax, cl 0x3C03, CF1 (bit koji je ispao)
- sal ax, cl 0xFC03, CF1 (bit koji je ispao)
- ror ax, cl 0xFC03, CF1 (poslednji
- rol ax, cl 0xC03F, CF1 rotirani bit)
- rcr ax, cl 0xBC03, CF1 (poslednj
- rcl ax, cl 0xC03D, CF1 izbaceni bit)
40Uslovni skokovi 1/2
- Relativni skok.
- Pomjeraj se posmatra kao oznaceni cijeli broj
velicine - 8 bita (short jump), ili
- 16-bita (near jump), ili
- 32-bita (near jump).
- Test pojedinacnih flegova
- jz (je), (Jump if Zero Jump if Equal)
- jnz (jne), (Jump if Not Zero Jump if Not Equal
- js, (Jump if Sign set)
- jns,
- jp (jpe), (Jump if Parity flag set Jump if
Parity even) - jnp (jpo), (Jumo if No Parity flag set Jump if
Parity odd)
41Uslovni skokovi 2/2
- Poredenje neoznacenih brojeva
- jb (jnae, jc) lt(Jump Below Jump Not Above or
Equal) - jnb (jae, jnc) gt
- jbe (jna) lt
- jnbe (ja) gt
- Poredenje oznacenih brojeva
- jl (jnge) lt(Jump Lower Jump Not Greater or
Equal) - jnl (jge) gt
- jle (jng) lt
- jnle (jg) gt
42if-then-else
Izracunavanje uslova.
- Viši programski jezici
- if (ecxlt0) blok1 else blok2
- Blok1 i blok2 su nizovi instrukcija
- Asembler
- cmp ecx,0 jbe blok1 jmp blok2blok1 jmp
daljeblok2 dalje
Ako je tacan, skace na blok1. U suprotnom na
blok2.
43Lokalne labele
- Smanjuju mogucnost slucajnog ponavljanja iste
labele. - Moguce koristiti 10 razlicitih
- ltcifragt
- Sa svakog mjesta je moguce referisati prvu
labelu - unazad
- ltcifragtb
- odnosi se na prvo pojavljivanje labele ltcifragt
prije tekuce instrukcije - unaprijed
- ltcifragtf
- odnosi se na prvo pojavljivanje labele ltcifragt
posle tekuce instrukcije
44Primjer upotrebe lokalnih labela
- Primjer 1 cmp ecx,0 je 1f jmp 2f1 jmp
1f2 1
- Primjer 21 add eax, ebx sub ebx, 1 test
ebx, 1 je 2f dec ebx2 jnz 1b
45Podrška za petlje 1/2
- Neke moguce implementacije
- Pomocu instrukcija uslovnog skoka
- Pomogu namjenskih instrukcija za formiranje
petlji - Pomocu potprograma i manipulacije povratnom
adresom (strogo izbjegavati). - Instrukcije
- loop lab
- loopz (loope) lab
- loopnz (loopne) lab
46Podrška za petlje 2/2
- Algoritam rada
- na pocetku instrukcije se prvo umanji ecx
ecxecx-1 - potom se provere uslovi izlaska iz petlje
- ecx0, za loop
- ecx0 ili zf0, za loope
- ecx0 ili zf1, za loopne
- Lab je labela pocetak petlje ili instrukcije
skoka na pocetak petlje. - Lab mora biti u opsegu -128..127B od adrese
sledece instrukcije. - jcxz lab skace na lab ako je ecx0
47Primjer, suma prvih N brojeva
- mov ecx, n inicijalizacija brojaca
- jcxz 2f ako je ecx 0, preskace se
petlja - mov eax, 0 pocetna vrijednost sume
- 1 add eax, ecx racunanje sume
- loop 1b skok na pocetak petlje
ako je ecxgt0 - 2 ... prva sledeca instrukcija
48Bezuslovni skok
- jmp lab skace na lab
- Za lab se mogu koristiti modovi adresiranja kao
i za podatke - Može se koristiti i indirektno memorijsko
adresiranje. - Primeri
- jmp eax skace se na adresu zapisanu u eax
- jmp eax skace se na adresu zapisanu na
adresi iz eax - jmp lab skace se na labelu lab
- jmp lab sa adrese lab se cita adresa skoka
- jmp DWORD PTR lab isto kao prethodno
49Minimum dva broja 1
- Napisati program koji sa standardnog ulaza
ucitava dva broja i na standardni izlaz ispisuje
manji od dva unijeta broja. - Traženje minimuma izdvojiti u funkciju u zasebnom
fajlu (koristiti stdcall konvenciju pozivanja). - Zadatak uraditi
- tako da se oba fajla napišu na asembleru,
- tako da se potprogram napiše na C-u, a program na
asembleru, - tako da se potprogram napiše na asembleru, a da
se program napiše na C-u.
50Uvoženje i izvoženje simbola
- Izvoženje
- Dvije sintakse
- .globl ltnaziv_simbolagt
- .global ltnaziv_simbolagt
- Ako je simbol definisan, ostace vidljiv i za fazu
povezivanja. - Ako simbol nije definisan, smatra se da se uvozi
spolja. - Uvoženje
- .extern ltnaziv_simbolagt
51p4b.s (potprogram)
- .data
- .globl izlazni_format
- izlazni_format
- .asciz "min(i, i) i\n"
- .text
- .globl min
- min 1
- enter 0, 0
- mov ebx, ebp8
- cmp ebx, ebp12 isto Å¡to i ebp12
- jle 1f
- mov eax, ebp12
- jmp 2f
- 1 mov eax, ebx
- 2 leave
- ret 8 1
- .end
52p4a.s (program)
- lea eax, ebp-4
- push eax
- sub eax, 4
- push eax
- push offset ulazni_format
- call scanf
- add esp, 12
-
- push ebp-8
- push ebp-4
- call min
- push eax
- push ebp-4
- push ebp-8
- push offset izlazni_format
- call printf
- add esp, 16
- leave
- .data
- ulazni_format
- .asciz "ii"
- .extern izlazni_format
- .text
- .extern printf
- .extern scanf
- .extern exit
- .globl _start
- _start
- call main
- push 0
- call exit
- .extern min
- main
- enter 8, 0
- and esp, 0xfffffff0
53Prevodenje, povezivanje i pokretanje
- Prevodenje asemblerskog koda
- as -o p4a.o p4a.s
- as -o p4b.o p4b.s
- Povezivanje
- ld -o p4 -dynamic-linker /lib/ld-linux.so.2
-l c p4a.o p4b.o - Pokretanje
- ./p4
54P5b.c (potprogram)
- char izlazni_format "min(i, i) i\n"
- int __attribute__((stdcall)) min(int a, int b)
- return a lt b ? a b
55p5a.s (program)
56Prevodenje, povezivanje i pokretanje
- Prevodenje
- as -o p5a.o p5a.s
- Prevodenje C koda
- gcc -c -o p5b.o p5b.c
- c prevesti samo do objektnog programa, bez
povezivanja - Povezivanje
- ld -o p5 -dynamic-linker /lib/ld-linux.so.2 -l c
p5a.o p5b.o - Pokretanje
- ./p5
- Disasembliranje objektnog fajla koji sadrži
funkciju min - objdump d1 Mintel2 p5b.o
57Disasembliran prevod C funkcije
- 00000000 ltmingt 1
- 0 55 push ebp
- 1 89 e5 mov ebp, esp
- 3 8b 45 08 mov eax, ebp0x8
- 6 39 45 0c cmp ebp0xc, eax
- 9 0f 4e 45 0c cmovle eax, ebp0xc
- d 5d pop ebp
- e c2 08 00 ret 0x8
58p6b.s (potprogram)
59p6a.c (program)
- includeltstdio.hgt
- extern char izlazni_format
- int __attribute__((stdcall)) min(int x, int y)
- int main()
- int x1, x2, z
- scanf("ii", x1, x2)
- z min(x1,x2)
- printf(izlazni_format, x1, x2, z)
-
- return 0
60Prevodenje, povezivanje i pokretanje
- Prevodenje
- gcc -c -o p6a.o p6a.c
- -c želi se samo prevesti zadati fajl, bez
pozivanja. - as -o p6b.o p6b.s
- Povezivanje
- ld -o p6 -dynamic-linker /lib/ld-linux.so.2 -L
/usr/lib/gcc/i686-linux-gnu/4.6/
/usr/lib/i386-linux-gnu/crt1.o /usr/lib/i386-linux
-gnu/crti.o /usr/lib/gcc/i686-linux-gnu/4.6/crtbeg
in.o p6a.o p6b.o -lgcc --as-needed -lgcc_s
--no-as-needed -lc -lgcc --as-needed -lgcc_s
--no-as-needed /usr/lib/gcc/i686-linux-gnu/4.6/crt
end.o /usr/lib/i386-linux-gnu/crtn.o - Prevodenje i povezivanje u jednoj komandi
- gcc o p6 p6a.c p6b.s
- za prikaz pojedinacnih komandi dodati opciju v
- Pokretanje
- ./p6
61Definisanje podataka i poravnavanje
- . balign bajt_multipl, bajt_za_dopunjavanje,
max - bajt_multipl1
- bajt_za_dopunu2
- max3
- Rezervisanje prostora u memoriji
- Bajt .byte init ,init...
- Rijec (2B) .word init ,init... .short
init ,init... - Dupla rijec (4B) .long init ,init... .int
init ,init... - Lista stringova .ascii lista_stringova_odvojen
ih_zapetama - Lista stringova sa \04 .asciz
lista_stringova_odvojenih_zapetama - Ponavljanje sadržaja
- .rept broj_ponavljanjasadržaj za
ponavljanje.endr
62Primjer
- a .byte 2
- jedan bajt kojem se pristupa sa a
- b .word 3, 8, 6
- 3 rijeci, sa b se pristupa prvoj, a sa b2 i b4
drugim dvijema. - c .asciz "Tekst"
- niz od 6 bajtova, zadnji je null.
- d .long c
- jedna dupla rijec sa ofsetom od c
- F .rep 4
- .byte 0,1
- .endr
- 8 bajtova inicijalizovanih sa 0,1,0,1,0,1,0,1
63Direktive
- .equ noviSimbol, izraz
- svako pojavljivanje noviSimbol zamjenjuje
vrijednošcu izraza. - .include file
- ukljucuje sadržaj fajla file na poziciju ove
direktive. - OFFSET expr
- vraca ofset izraza.
- BYTE PTR expr
- pristup bajtu.
- WORD PTR expr
- pristup rijeci.
- DWORD PTR expr
- pristup dvostrukoj rijeci.
64Sabiranje niza brojeva
- Napisati program koji sa standardnog ulaza
ucitava i sabira niz brojeva. Program prvo ucita
broj elemenata niza, a potom i elemente niza.
Broj elemenata nije unapred poznat, pa se prostor
alocira na steku. Smatrati da ce stek biti
dovoljno veliki za smeštanje niza, kao i da se
zbir racuna unutar potprograma.
65Sabiranje niza brojeva
- .data
- poruka
- .asciz "Unesite broj elemenata\
- niza, pa zatim elemente niza.\n"
- ulazni_format
- .asciz "i"
- izlazni_format
- .asciz "Suma elemenata unijetog\
- niza je i\n"
- .text
- .extern scanf
- .extern printf
- .extern exit
- .globl _start
- _start
- call main
- push 0
- call exit exit(0)
- prvi argument broje elemenata
- naredni argumenti elementi niza
- saberi
- enter 0, 0
- xor eax, eax sum 0
- mov ecx, ebp8 i N
-
- jcxz 2f if (i0) ret 0
- adresa prvog elementa ebp12
- iN .. 1
- adrese elemenata niza
- ebp12 (i-1)4
- sumnizi-1
- 1 add eax, ebp4ecx8
- loop 1b
- 2 leave
66Sabiranje niza brojeva
- 1 push ecx
- push ebx
- push offset ulazni_format
- call scanf scanf(i, adr_elementa)
- add esp, 8
-
- pop ecx
- add ebx, 4 adr_elementa
- loop 1b
- push DWORD PTR ebp-4 push N
- call saberi eax sum
- add esp, 4
- push eax
- push offset izlazni_format
- main
- enter 4, 0
- push offset poruka
- call printf
- add esp, 4
- lea eax, ebp-4 eax ebp-4
- push eax 2. arg za scanf
- push offset ulazni_format 1. arg
- call scanf
- add esp, 8
-
- mov ecx, ebp-4
- jcxz 2f if (N0) goto exit
- mov ebx, ecx
- shl ebx, 2
67Rekurzivne funkcije
- Napisati rekurzivnu funkciju koja sabira brojeve
u opsegu 0..N. - Koristiti stdcall konvenciju pozivanja.
68Primjer rekurzija, sabiranje N..0
EBP pokazuje ovdje EBP8 pokazuje na poziciju
koja sadrži vrijednost 3
EBP pokazuje ovdje. Sa EBP8 se cita 3 i dodaje
na tekucu sumu EAX EAX3 (33). Ovo je i
povratna vrijednost funkcije.
- suma
- push ebp
- mov ebp, esp
- mov eax, ebp8 citanje parametra sa steka
- cmp eax, 0 da li se doslo do 0?
- je dalje ako jeste, skoci na kraj i
- vrati 0
- dec eax ako nije, pozovi suma(i-1)
- push eax
- call suma
- add eax, ebp8 na tekucu sumu (0..i-1)
dodaj i - dalje pop ebp
- ret 4 po povratku oslobodi prostor
rezervisan - za parametar na steku
Promjer poziva sa parametrom 3 3 vrijednost
programa proslijedena pred poziv retEIP adresa
van funkcije EBPold1 2 retEIP adresa add
EAX, EBP8 EBPold2 1 retEIP adresa add EAX,
EBP8 EBPold3 0 retEIP adresa add EAX,
EBP8 EBPold3
Pošto je sa steka ocitano 3, što je razlicito od
0, na stek se stavlja 3-1, Å¡to je parametar za
naredni poziv
EBP pokazuje ovdje. Sa EBP8 se cita 2 i dodaje
na tekucu sumu EAX EAX2 (12)
EBP pokazuje ovdje EBP8 pokazuje na poziciju
koja sadrži vrijednost 2
Pošto je sa steka ocitano 2, što je razlicito od
0, na stek se stavlja 2-1, Å¡to je parametar za
naredni poziv
EBP pokazuje ovdje. Sa EBP8 se cita 1 i dodaje
na tekucu sumu EAX EAX1 (01)
EBP pokazuje ovdje EBP8 pokazuje na poziciju
koja sadrži vrijednost 1
Pošto je sa steka ocitano 1, što je razlicito od
0, na stek se stavlja 1-1, Å¡to je parametar za
naredni poziv
EBP pokazuje ovdje EBP8 pokazuje na poziciju
koja sadrži vrijednost 0. Pošto je 0, skace se
na kraj. Primjetiti da je u ovom trenutku EAX0
Å¡to je pocetna suma
Sada se krece sa izlascima iz ranije ucinjenih
poziva ove funkcije. Svaki put se po povratku na
tekucu sumu doda vrijednost parametra iz tekuceg
poziva. Tekuca suma se uvijek zapiše u EAX i u
njemu se i ostavlja.
69Uslovno prevodenje
- Pocetak bloka sa uslovnim prevodenjem
- .if apsolutni_izraz
- da li je vrijednost apsolutnog izraza razlicita
od nule? - .ifdef name
- da li je simbol name definisan?
- .ifndef
- Opciono može da se pojavi i else grana
- .else
- .elseif
- Na kraju mora da se pojavi
- .endif
70Makroi 1/2
- Pocetak makroa
- .macro name argdef_val , argdef_val
- name naziv makroa
- arg parametri
- def_val podrazumijevana vrijednost parametra
- Kraj makroa
- .endm
- Izlazak iz makroa sa sredine
- .exitm
- Upotreba parametara
- \naziv_parametra
71Primjer upotrebe makroa
- Definicija
- .macro INVOKE, func, p1, p2, p3
- push \p3
- push offset \p2
- push \p1
- call \func
- add esp, 12
- .endm
- Poziv
- INVOKE write,1,poruka,duzina_poruke
72Primjer upotrebe makroa
- Definicija
- .macro sum from0, to5
- .long \from
- .if \to-\from
- sum "(\from1)",\to
- .endif
- .endm
- Pozivsum 0,5
- Rezultat1
- .long 0
- .long 1
- .long 2
- .long 3
- .long 4
- .long 5
73Makroi 2/2
- .irp param, ltarg,,arg...gt
- ovaj segment koda se ponavlja onoliko puta
koliko ima - argumenata i to tako da se svaki put umjesto
svakog pojavljivanja - param zamjeni jedna vrijednost arg.
- .endm
- .irpc param, ltstringgt
- isto kao prethodno, osim cto su argumenti slova
- navedenog stringa
- .endm
- \ - operator prepoznavanja parametra u tekstu
74Primjeri upotrebe makroa
- Ulaz
- .irp param,0,4,8
- move d\param,BX\param
- .endr
- Rezultat
- move d0, BX0
- move d4, BX4
- move d8, BX8
- Ulaz
- .irpc param,048
- move d\param,BX\param
- .endr
- Rezultat
- move d0, BX0
- move d4, BX4
- move d8, BX8
75Razlike izmedu Intel i ATT sintakse
Intel ATT
Redosled operanada dst, src src, dst 1
Indirektno adresiranje registar (registar)
Prefix za registre nema
Prefix za konstante nema
Prefix za apsolutne adrese jump i call nema
Velicina operanada u memoriji na osnovu direktiva uz operand na osnovu sufiksa mnemonika 2
Daleke adrese sectionoffset section, offset
76Primjer Intel i ATT sitaksi
- push ebp
- mov ebp, esp
- mov eax, ebp0x8
- cmp ebp0xc, eax
- cmovle eax, ebp0xc
- pop ebp
- ret 0x8
- push ebp
- mov esp, ebp
- mov 0x8(ebp), eax
- cmp eax, 0xc(ebp)
- cmovle 0xc(ebp), eax
- pop ebp
- ret 0x8
77Primjeri rada sa WIN32 API
78Zdravo svete (Windows)
- .intel_syntax noprefix
- .arch i386
- .extern _MessageBoxA_at_16 PROC
- .extern _ExitProcess_at_4 PROC
- .global _start
- .equ MB_OK, 0
- .data
- nl
- .ascii "Zdravo svete\0
- .asciz "Zdravo svete"
- .text
- _start
- push MB_OK
- push offset nl
- push offset nl
- push 0
- call _MessageBoxA_at_16
- push 0
- call _ExitProcess_at_4
- .end
79Prevodenje
- Asembliranje
- as zdravo_svete.s -o zdravo_svete.obj
- korišcena opcija -o ltoutput_file_namegt
- Linkovanje (povezivanje)
- ld -o zdravo_svete.exe zdravo_svete.obj -l user32
-l kernel32 - korišcene opcije
- -o ltoutput_file_namegt
- -l ltlibrary_namegt
80Primjer citanje jednog znaka i vracanje u
registru
- push 0
- push ebx
- push 1 broj znakova za citanje
- push eax adresa bafera za podatke
- push stdin stdin handle (naredni slajd)
- call _readconsolea_at_20 stdcall
- mov eax, ebp - 4
- and eax, 0ffh
-
- pop ebx
- leave
- ret
- .intel_syntax noprefix
- .data
- stdin .long 0
- .text
- .extern _readconsolea_at_20
- .type readc, _at_Function
- readc
- enter 8, 0
- push ebx
- lea eax, ebp-4 adresa bafera za podatke
-
- lea ebx, ebp-8 bafer za broj procitanih
- znakova
81stdin i stdout rucke
- Da bi se mogao vršiti ispis na konzolu, na
pocetku programa (prije prvog ispisa) je
neophodno dohvatiti stdout handle - .equ STD_OUTPUT_HANDLE, -11
- push STD_OUTPUT_HANDLE
- call GetStdHandle
- mov stdout, eax
- Da bi se moglo vršiti citanje standardnog ulaza
pripadajuce konzole, na pocetku programa (prije
prvog citanja) je neophodno dohvatiti stdin
handle - .equ STD_INPUT_HANDLE, -10
- push STD_INPUT_HANDLE
- call GetStdHandle
- mov stdin, eax
82Inline asembler
- Na mesto naredbe se ubacuje
- _ _asm_ _("
- niz redova sa asemblerskim naredbama završenih
sa - ")
- ili
- _ _asm_ _("instrukcija \n" output input
modify) - output "tmp"(naziv promenljive)
- input tmp"(naziv ulazne promjenljive)
- modify "registar" spisak registara na cije
vrijednosti kompajler ne treba da racuna nakon
izvršavanja bloka. - tmp privremena lokacija (objašnjena na sledecem
slajdu).
83Inline asembler polje tmp
- tmp oznaka privremene lokacije (registra ili
memorije) - ova lokacija ce biti korišcena u asembleru umesto
promenljive. - u asembleru se referiše sa ltredni_brojgt
- input -gt prije instrukcija iz asm bloka, u tmp ce
se ucitati vrednost promenljive navedene u
zagradama. - output -gt nakon instrukcija iz asm bloka,
vrednost tmp ce se upisati u promenljivu navedenu
u zagradama. - za tmp je moguce koristiti
- registre (eax, ebx, ecx, edx, esi, edi, r-bilo
koji registar)1 - memoriju (memory)
84Inline asembler - primer
- int t
- int main()
- int x1, x2, z
-
- __asm__(
- // ".intel_syntax noprefix\n1
- "mov ebx, 2\n"\
- "add ebx, 3\n"
- "mov 0, ebx\n"\
- "mov 1, ebx\n"
- // ".att_syntax\n1
- "c"(x1), "m"(z)\
- "a"(x2), "m"(t)\
- "ebx"\
- )
- return 0
- Izlaz koji se dobije kada se c kod prevede na
asm - mov eax, DWORD PTR ebp-162
- mov ebx, eax3
- add ebx, DWORD PTR t4
- mov ecx5, ebx
- mov DWORD PTR ebp-206, ebx
- mov esi, ecx7
- mov DWORD PTR ebp-12, esi
85Microsoft asembler
86Definisanje potprograma (Microsoft asembler)
- name PROC FARNEAR start potprograma.
- Može biti
- bliski (pri pozivu se koristi samo EIP) ili
- daleki (koriste se i CS i EIP).
- Podrazumjevana vrijednost zavisi od modela (flat
near) - Moguce definisati i konvenciju pozivanja, kao i
parametre - ltnazivgtPROCltlanggtltostali_atributigt
,ltparamgtlttipgt ltlanggt - neka od konvencija
pozivanja - U slucaju definisanja konvencije pozivanja, umecu
se i odgovarajuce instrukcije za navedenu
konvenciju pozivanjanpr. za C, na pocetku
PUSH EBP MOV EBP, ESPi pred svaki ret
POP EBP - name ENDP kraj potprograma name.
- Ne proizvodi nijednu instrukciju, pa je potrebno
ispred staviti ret ili neku drugu instrukciju za
kontrolu toka, kako bi se osigurali da nikada
nece doci do neregularne situacije.
87Uvoženje i izvoženje simbola
- public name,name... izvoz iz fajla
- extern nametype ,nametype... uvoz
- Neki asembleri dozvoljavaju izostavljanje tipa
- U MASM, tip je obavezan
- Novi pristup je direktiva externdef koja mijenja
obje prethodne direktive - Ukoliko je simbol definisan u fajlu u kojem se
nalazi direktiva, tada je to simbol koji se
izvozi - Ukoliko simbol naveden u direktivi nije
definisan, tada je to simbol koji se uvozi - Sintaksa kao kod EXTERN direktive
88Definisanje prototipa potprograma
- Direktiva PROTO
- Prednosti
- definiše prototip potprograma gt poziv sa
INVOKE - dodjeljuje nazive parametrima (umjesto pomjeraja)
- ova direktiva automatski generiše i odgovarajuci
EXTERNDEF - Sintaksa
- ltnazivgtPROTOltlanggtltostali_atributigt
,ltparamgtlttipgt - ltlanggt - neka od konvencija pozivanja.
- Neophodno je na isti nacin definisati i sam
potprogram (PROTO zamjeniti sa PROC). - Moguce definisati i lokalne promjenljive
- LOCAL ltlvargtlttipgt , ltlvargtlttipgt
- gt pogodno za pristupanje lokalnim
promjenljivim bez racunanja pomjeraja.
89INVOKE
- Potprogrami definisani u skladu sa prethodnim
slajdom, pomocu INVOKE mogu biti pozvani slicno
pozivima u višim programskim jezicima. - Primjer
- f1 PROC C par1DWORD, par2DWORD
- mov EAX, par1
- add EAX, par2
- f1 ENDP
- f1 PROTO C param1DWORD, param2DWORD
- INVOKE f1, EAX, EBX ekvivalentno sa
- push EBX
- push EAX
- call f1
- add ESP, 8
90Definisanje segmenata
- Pojednostavljene direktive (MASM)
- klasa segmenta. Standardno
- .stack stek (ne mora da se navodi)
- .code programski kod
- .data inicijalizovani podaci
- .data? neinicijalizovani podaci
- Na pocetku programa navesti
- .386P za koji procesor su naredbe
- .model flat za linearne adrese
- iza flat je moguce navesti standardnu konvenciju
pozivanja potprograma
91Start programa
- end label kraj programa
- ako postoji label, to je oznaka pocetka programa
- Pri linkovanju više fajlova, samo jedan smije
imati ulaznu tacku (pocetak)
92Definisanje podataka i poravnavanje
- even poravnava sledecu promjenljivu na parnu
adresu. Dobra praksa zbog bržeg pristupa
memoriji. - Rezervisanje prostora u memoriji
- Bajt
name DB init ,init... - Rijec (2B)
name DW init ,init... - Dupla rijec (4B)
name DD init ,init... - Dvostruka dupla rijec (8B)
name DQ init ,init... - Za svaku pocetnu vrijednost se rezerviše jedna
lokacija. - count DUP (init ,init...)
- ponavlja ono Å¡to je u () onoliko puta koliko je
vrijednost count. - ? neinicijalizovana lokacija
93Primjer
- a DB 2
- jedan bajt kojem se pristupa sa a
- b DW 3 DUP(?)
- 3 neinicijalizovane rijeci, sa b se pristupa
prvoj, a sa b2 i b4 naredne dvije - c DB "Tekst"
- niz od 6 bajtova
- d DD c
- jedna dupla rijec sa segmentom i ofsetom od c
- f DB 4 DUP(0,1)
- 8 bajtova inicijalizovanih sa 0,1,0,1,0,1,0,1
94Direktive
- name EQU expr svako pojavljivanje name
zamjenjuje sa expr. - include file ukljucuje sadržaj fajla file na
poziciju ove direktive. - OFFSET expr vraca ofset izraza.
- BYTE PTR expr pristup bajtu.
- WORD PTR expr pristup rijeci.
- LENGTH var broj elemenata u nizovnim prom.
95Bezimene labele (Microsoft asembler)
- Kao labela se može koristiti _at__at_
- Na labelu se referiše sa
- _at_B - ako se želi prva bezimena labela unazad
- _at_F - ako se želi prva bezimena labela unaprijed
96Uslovno prevodenje
- IFDEF name uslovno prevedenje.
- ELSE
- ENDIF
97Makroi 1/2
- Pocetak makroaname MACRO arg ,arg...
- name naziv makroa
- Arg - parametri
- ENDM kraj makroa.
- LOCAL name ,name... lokalni simboli za makro.
- Neophodno za labele u makrou, kako bi se jedan
makro mogao ekspandovati više puta u okviru
jednog koda bez problema dupliranih labela.
98Makroi 2/2
- IRP param, ltarg,,arg...gt
- ovaj segment koda se ponavlja onoliko puta
koliko ima - argumenata i to tako da se svaki put umjesto
svakog pojavljivanja - param zamjeni jedna vrijednost arg.
- ENDM
- IRPC param, ltstringgt
- isto kao prethodno, osim cto su argumenti slova
navedenog stringa - ENDM
- - operator prepoznavanja parametra u tekstu