1 / 98

X86 asembler

X86 asembler. 80 386 procesor. 32 -bitna CISC arhitrktura . Pretežno dvoadresna mašina. Veličina memorijskog adresnog prostora: 4GB. Adresibilna jedinica: bajt. Veličina podataka u instrukcijama: bajt, reč ( word )– dva uzastopna bajta,

deanna
Télécharger la présentation

X86 asembler

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. X86 asembler

  2. 80386 procesor • 32-bitna CISC arhitrktura. • Pretežno dvoadresna mašina. • Veličina memorijskog adresnog prostora: 4GB. • Adresibilna jedinica: bajt. • Veličina podataka u instrukcijama: • bajt, • reč (word)– dva uzastopna bajta, • dvostruka reč (doubleword) – četiri uzastopna bajta.

  3. Redosled bajtova podatka u memoriji • Little-endian – viši bajt na višoj adresi. • Riječi: • (a): 34 12 • (a+1): 56 34 • (a+2): 78 56 • Duple riječi: • (a) : 78 56 34 12

  4. Zdravo svete! (Linux, int) 3 • .intel_syntax noprefix.arch i386.data1poruka:.ascii “Zdravo svete!\n“kraj_poruke:.equ duzina_poruke, kraj_poruke – poruka.text1 • .globl _start_start:mov ebx, 1# mov ecx, offset porukalea ecx, porukamov edx, duzina_porukemov eax, 4int 0x80 2mov ebx,0mov eax,1int 0x80 2

  5. Prevođenje, povezivanje i pokretanje • Asembliranje: • as zdravo_svete.s –o zdravo_svete.o • korišćena opcija: -o <output_file_name> • Linkovanje (povezivanje): • ld zdravo_svete.o –o zdravo_svete • korišćena opcija: -o <output_file_name> • Pokretanje • ./zdravo_svete

  6. Prevođenje i povezivanje pomoću gcc • Asembliranje: gcc -c -o zdravo_svete.o zdravo_svete.s • korišćene opcije: • -o <output_file_name> • -c Prevedođenje i asembliranje, bez linkovanja • Linkovanje (povezivanje): gcc -o zdravo_svete -nostartfiles zdravo_svete.o • korišćene opcije: -o <output_file_name> -nostartfilesPoveži bez standardnih startup fajlova. • Ili, i prevođenje 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 pokreće. -### Kao prethodno, ali bez izvršavanja komandi.

  7. Asemblerske naredbe (Intel sintaksa) • [labela:]mnemonik[operandi] [#komentar] • Labela predstavlja adresu na kojoj se nalazi naredba. • mnemonik je simbolički zapisana komanda. • Mogu biti do dva operanda. • Prvi je uvijek odredište, a nekad i izvorište. • Drugi je izvorište.

  8. Transfer podataka • mov dst, src # dst = src • lea dst, src # dst = offset(src)1 • lds dst, src # ds:dst = src • les dst, src # es:dst = src • xchg op1, op2 # mijenja vrijednosti # u operandima op1 i op2

  9. Programski dostupniregistri(flat mode, aplikativni režim) • Opštenamjenski (32-bitni): • eax, ebx, ecx,edx, esiiedi. • 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 početak memorije. • Registri dostupni samo korišćenjem posebnih instrukcija • programski brojač eip, • statusna riječ procesora eflags.

  10. Preslikavanje logičke u linearnu (flat) adresu • Logička 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 logičku adresu 0, tako da je programeru dostupan ceo prostor od 4GB koristeći samo ofset i ne vodeći računa o segmentima tzv. Linearni adr. prostor • Po potrebi se može uključiti i straničenje, kada se logička adresa preslikava u fizičku adresu.

  11. Opš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 -> • ah – viši bajt, • al – niži bajt. • Imaju i posebne namene: • eax – akumulator, • ebx – bazni registar za adresiranje, • ecx – brojački registar, • edx – pomoćni registar za podatke u nekim instrukcijama, • esi i edi – indeksiranje pri adresiranju.

  12. Registri za rad sa stekom • esp – pokazivač na vrh steka • pokazuje na zauzetu lokaciju na vrhu steka, • umanjuje se pre smeštanja podatka, • uvećava se posle skidanja podatka. • ebp – bazni registar za pristup argumentima potprograma i lokalnim promenljivim • Radi sa: • Rečima (16 bita – esp se menja za 2) • Duplim rečima (32 bita – esp se menja za 4)

  13. Rad sa stekom • pushsrc ;stavlja na stek src • pop dst;sa steka upisuje u dst • pushfd;čuva eflags na steku • popfd;restaurira eflags sa steka ( ; u neprivilegovanom režimu ; bitovi posle OF neće se promeniti) • pushf/popf ; koristi samo donjih 16 bita eflags • pushad/popad ;čuvanje svih registara na steku: ; eax, ecx, edx, ebx, esp, ebp, ; esi, edi.

  14. Statusna riječ procesora VM RF NT IOPL OF DF IF TF SF ZF AF PF CF • CF – prenos. • PF – parnost. • AF – pomoćni prenos za BCD aritmetiku. • ZF – rezultat nula. • SF – negativan rezultat. • TF – prekid posle svake instrukcije. • IF – maskiranje svih maskirajućih prekida. • DF – smjer za operacije nad stringovima. • OF – prekoračenje. • IOPL – I/O priviledge level • NT – nested task flag • RF – resume flag • VM – virtual 8086 mode

  15. Načini adresiranja 1/2 • Neposredno: • mov eax, 10 • add ebx, 20h • Registarsko direktno (svi registri): • mov eax, 2 • mov edi, ebx • mov [ebp+6], ecx • Memorijsko direktno: • mov eax, suma • mov niz+6, edx ...

  16. Načini adresiranja 2/2 • Registarsko indirektno (svi opšte namene): • mov [ebx], eax • Registarsko indirektno sa pomerajem: • mov [eax+88h], 2 • mov niz[edx], 2 • Bazno indeksno (adresa se sastoji od dva registra): • mov [ebx][edx], eax • Bazno indeksno sa pomjerajem (kao prethodno plus pomjeraj): • mov eax, niz[ebx][edi]

  17. Skaliranje indeksa • Opšti oblik: • <konstanta>[<bazna_adresa>+<faktor>*<indeks>] • <faktor> može biti: • 1, • 2, • 4. • mov eax, suma[ebx+4*esi] • mov vrsta[edx+2*eax], bx

  18. Napomene • 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 podrazumjevanogsegmentnog registra: • movax,ds:[ebp+4] • Flat režim = samo jedan segmentveličine 4GB.

  19. Sistemski pozivi (Linux) • Tri načina: • direktno, • kroz prekid 0x80, • kod novijih procesora, instrukcijama SYSENTER i SYSEXIT, • indirektno, preko funkcija omotača iz standardne biblioteke. • int 0x80 • eax = 1: exit(int) • ebx: povratna vrijednost programa. • eax = 3: read(int, char*, int) • ebx: ručka fajla (0 za standardni ulaz), • ecx: adresa bafera, • edx: veličina bafera u B. • eax = 4: write(int, char*, int) • analogno prethodnom (1 je ručka za standardni izlaz).

  20. Zdravo svete! (Linux, int) 3 • .intel_syntax noprefix.arch i386.data1poruka:.ascii “Zdravo svete!\n“kraj_poruke:.equ duzina_poruke, kraj_poruke – poruka.text1 • .globl _start_start:mov ebx, 1# mov ecx, offset porukalea ecx, porukamov edx, duzina_porukemov eax, 4int 0x80 2mov ebx,0mov eax,1int 0x80 2

  21. Zdravo svete! (Linux, libc) 1 • .intel_syntaxnoprefix.arch i386.dataporuka:.asciz "Zdravosvete!\n”kraj_poruke:.equduzina_poruke, kraj_poruke – poruka.text .extern write.extern exit • .globl _start _start:push duzina_porukepush offset porukapush 1call write add esp, 12 #write(1,&poruka,# duzina_poruke); push 0call exit # exit(0);.end

  22. Prevođenje, 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: • uključuje biblioteku libc.a1, • važno: navesti biblioteku posle objektnih fajlova koji je koriste2. • dynamic-linker/lib/ld-linux.so.2 • uključuje biblioteku za dinamičko povezivanje. • Pokretanje • ./zdravo_svete

  23. Potprogrami • Počinje labelom i opciono: • u redu ispred labele: .type <labela>, @Function • za potrebe umetanja informacija za debug: • na početku .func <naziv> [, <labela>]1 • 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: • calldst • near poziv -> na steku se čuva EIP (u flat režimu se koristi ovaj pristup) • far poziv -> na steku se čuvaju CS i EIP • skače na dst

  24. Proslijeđivanje 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 -> 1 • Da li je dozvoljena rekurzija? • Pozivanje u prekidnim rutinama? • Pozivanje u konkurentnim nitima?

  25. Proslijeđivanje parametara preko steka • Parametri se prije poziva ostavljaju na steku. • U funkciji im se pristupa pomoću registra EBP. • Zato svaka funkcija: • počinje sa:pushebpmovebp, espilienter 0, 01 • završava se sa:movesp, ebp ili leave2pop ebp • Ovako je obezbjeđeno da svaki poziv funkcije ima svoj zapis na steku (prikaz na sledećem slajdu).

  26. Zapis poziva funkcije Bliski poziv Zapis tekućeg poziva neke funkcije Loc[m] -4*m ... enter 4*m,0 Loc[1] -4 EBPstaro retEIP +4 call naziv_funkcija Param[1] +8 Pred poziv funkcije: push param[n] … push param[1] ... Param[n] +4+4*n ESP EBP

  27. Instrukcija enter • enter op1, op2: • op1: • broj bajtova koje je potrebno rezervisati za lokalne prom. • 16-bitna neposredna konstanta. • op2: • dubina ugniježđenosti funkcije (0-31), • govori koliko pokazivača na prethodne okvire treba iskopirati u tekući. • algoritam: 1 • pushebp • movebp, esp • Na stek doda pokazivače na okvirove prethodnih nivoa (stare vrednosostiepb registra) • subesp, op1

  28. Konvencije pozivanja potprograma • Konvencija pozivanja potprograma definiše: • kako se poravnava stek, • kako se prosleđuju parametri, • ko radi oslobađanje prostora sa steka, • kako se vraća vrednost, • koji registri mogu da se koriste u funkciji bez da se čuvaju. • Konvencije koje se koriste u gcc-u: • cdecl (podrazumjevana) • stdcall • fastcall

  29. cdecl 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 oslobađa pozivaoc: • izuzetak je skriveni pokazivač, kojeg oslobađa pozvana funkcija. • Vrednost se najčešće vraća u registru: • 1 bajt -> AL • 2 bajta -> AX • 4 bajta -> EAX (naredni primjer) • 8 bajtova -> EDX:EAX • struktura ili klasa -> preko skrivenog pokazivača 2 • Funkcija ne mora da čuva registre: eax, ecxiedx

  30. Razlike stdcall i fastcall u odnosu na stdcall • stdcall • pozvani potprogram skida sve argumente sa steka • fastcall • prva dva argumenta, ako su celobrojnog tipa, prosleđuju se: • prvi u ecx • drugi u edx • ostali, kao i oni koji nisu celobrojnog tipa1 prosleđuju se preko steka • pozvani potprogram skida sve argumente sa steka • u slučaju da je promenljiv broj argumenata, na stek se stavljaju svi.

  31. Napisati potprogram za sabiranje dva broja koristeći stdcall i cdecl konvencije 1 • Potprogram:stdcallsaberi:enter 0, 0moveax, [ebp+8]addeax, [ebp]+12leaveret 8 cdeclsaberi:enter 0, 0moveax, [ebp+8]addeax, [ebp]+12leaveret • Primjer poziva:push broj1push broj2call saberimov rezultat, eaxpush broj1push broj2call saberimov rezultat, eaxadd esp, 8

  32. Napisati potprogram za sabiranje dva broja ? 58 EAX push 25 push 33 call saberi retAdr: mov rezultat, eax saberi: enter 0, 0 mov eax, [ebp+8] add eax, [ebp]+12 leave ret 8 EBP_old retAdr 33 33 25 25 ESP EBP

  33. Vraćanje vrijednosti preko steka typedefstruct { 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); } <f>: push ebp movebp, esp sub esp, 0x10 # za lokalne promjenljive moveax, 0xc[ebp] # eax = x mov [ebp-0x8], eax # a.a = eax moveax, [ebp+0x10] # eax + y mov[ebp-0x4], eax # b.b = eax movecx, [ebp+0x8] # ecx = &ret_bafer moveax, [ebp-0x8] # eax = a.a movedx, [ebp-0x4] # edx = a.b mov[ecx], eax # ret_bafer.a = eax mov[ecx+0x4], edx # ret_bafer.b = edx moveax, [ebp+0x8] # eax = &ret_bafer leave ret 0x4 # “oslobađa” skriveni parametar

  34. Sabiranje i oduzimanje • adddst, src # dst=dst+src • adcdst, src # dst=dst+src+cf • subdst, src # dst=dst-src • sbbdst, src # dst=dst-src-cf • negdst # dst=-dst • incdst # dst=dst+1 • dec dst # dst=dst-1 • cmp src1, src2 # setujeflegove na osnovu # src1-src2

  35. Množenje i dijeljenje • mul src # neoznaceno množenje • imul src # označeno 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 dx:ax • src (32-bitni) množi sa eax i rezultat ostavlja u edx:eax • div src # neoznačeno dijeljenje • idiv src # označeno dijeljenje • Dijeli ax sa src (8-bitni) i rezultat ostavlja u al, a ostatak u ah. • Dijeli dx:ax sa src (16-bitni) i rezultat ostavlja u ax, a ostatak u dx • Dijeli edx:eax 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

  36. Proš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

  37. Logičke 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

  38. Pomjeranje i rotiranje • shldst, cnt # pomjeranje logički lijevo • saldst, cnt # pomjeranje aritmetički lijevo • shrdst, cnt # pomjeranje logički desno • sar dst, cnt # pomjeranje aritmetički desno • rordst, cnt # rotiranje desno • roldst, cnt # rotiranje lijevo • rcrdst, cnt # rotiranje kroz cf desno • rcldst, cnt # rotiranje kroz cf lijevo • cnt može biti: • 1, • neposredna vrijednost ili • registar cl.

  39. Primjer • stanje prije: ax=0xf00f, CF=0, cl=2 • shlax, cl # 0xC03C, CF=1 (bit koji je ispao) • salax, cl # 0xC03C, CF=1 (bit koji je ispao) • shrax, cl # 0x3C03, CF=1 (bit koji je ispao) • salax, cl # 0xFC03, CF=1 (bit koji je ispao) • rorax, cl # 0xFC03, CF=1 (poslednji • rolax, cl # 0xC03F, CF=1 rotirani bit) • rcrax, cl # 0xBC03, CF=1 (poslednj • rclax, cl # 0xC03D, CF=1 izbačeni bit)

  40. Uslovni skokovi 1/2 • Relativni skok. • Pomjeraj se posmatra kao označeni cijeli broj veličine: • 8 bita (short jump), ili • 16-bita (near jump), ili • 32-bita (near jump). • Test pojedinačnih 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)

  41. Uslovni skokovi 2/2 • Poređenje neoznačenih brojeva: • jb (jnae, jc) <(Jump Below; Jump Not Above or Equal) • jnb (jae, jnc) >= • jbe (jna) <= • jnbe (ja) > • Poređenje označenih brojeva: • jl (jnge) <(Jump Lower; Jump Not Greater or Equal) • jnl (jge) >= • jle (jng) <= • jnle (jg) >

  42. if-then-else Izračunavanje uslova. • Viši programski jezici: • if (ecx<=0) {blok1 } else { blok2} • Blok1 i blok2 su nizovi instrukcija • Asembler: • cmp ecx,0jbe blok1jmp blok2blok1:…jmp daljeblok2:…dalje:… Ako je tačan, skače na blok1. U suprotnom na blok2.

  43. Lokalne labele • Smanjuju mogućnost slučajnog ponavljanja iste labele. • Moguće koristiti 10 različitih: • <cifra>: • Sa svakog mjesta je moguće referisati prvu labelu: • unazad: • <cifra>b • odnosi se na prvo pojavljivanje labele “<cifra>:” prije tekuće instrukcije • unaprijed • <cifra>f • odnosi se na prvo pojavljivanje labele “<cifra>:” posle tekuće instrukcije

  44. Primjer upotrebe lokalnih labela • #Primjer 1:cmp ecx,0je 1fjmp 2f1:…jmp 1f2:…1:… • #Primjer 2:1: add eax, ebx sub ebx, 1 test ebx, 1 je 2f dec ebx2: jnz 1b

  45. Podrška za petlje 1/2 • Neke moguće implementacije: • Pomoću instrukcija uslovnog skoka • Pomogu namjenskih instrukcija za formiranje petlji • Pomoću potprograma i manipulacije povratnom adresom (strogo izbjegavati). • Instrukcije: • loop lab • loopz (loope) lab • loopnz (loopne) lab

  46. Podrška za petlje 2/2 • Algoritam rada: • na početku instrukcije se prvo umanji ecx: ecx=ecx-1 • potom se provere uslovi izlaska iz petlje: • ecx==0, za loop • ecx==0 ili zf==0, za loope • ecx==0 ili zf==1, za loopne • Lab je labela početak petlje ili instrukcije skoka na početak petlje. • Lab mora biti u opsegu -128..+127B od adrese sledeće instrukcije. • jcxz lab ;skače na lab ako je ecx=0

  47. Primjer, suma prvih N brojeva mov ecx, n #inicijalizacija #brojača jcxz 2f #ako je ecx = 0, preskače se #petlja mov eax, 0 #početna vrijednost #sume 1: add eax, ecx #računanje sume loop 1b #skok na početak #petlje ako je # ecx>0 2: ... #prva sledeća instrukcija

  48. Bezuslovni skok • jmplab # skace na lab • Za lab se mogu koristiti modovi adresiranja kao i za podatke • Može se koristiti i indirektno memorijsko adresiranje. • Primeri: • jmpeax # skače se na adresu zapisanu u eax • jmp [eax] # skače se na adresu zapisanu na adresi iz eax • jmplab # skače se na labelulab • jmp [lab] # sa adrese lab se čita adresa skoka • jmp DWORD PTR lab # isto kao prethodno

  49. Minimum dva broja 1 • Napisati program koji sa standardnog ulaza učitava 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.

  50. Uvoženje i izvoženje simbola • Izvoženje: • Dvije sintakse: • .globl <naziv_simbola> • .global <naziv_simbola> • Ako je simbol definisan, ostaće vidljiv i za fazu povezivanja. • Ako simbol nije definisan, smatra se da se uvozi spolja. • Uvoženje: • .extern <naziv_simbola>

More Related