These are the slides for the presentation I delivered as the keynote address of the 2nd Asian Digital Storytelling Congress.
The digistal stories have been replaced with links to their place on the web wherever possible. The full text is on the digistories.co.uk website.
These are the slides for the presentation I delivered as the keynote address of the 2nd Asian Digital Storytelling Congress.
The digistal stories have been replaced with links to their place on the web wherever possible. The full text is on the digistories.co.uk website.
1. Úvod do x86 strojového kódu
a assembleru
Nudný ale nevyhnutný
2. Na čo preBoha assembler?
● Znalosť vs. využívanie
● Kvalitná znalosť vyžaduje aspoň nejaké využívanie
● Využívanie neznamená len programovanie v ňom
● Využitie:
● Reverse engineering
● Driver / system level programming
● Copy protection
● Machine code manipulation (compiler, packer, analyzer...)
● ????
● Profit
3. X86 milestones
● 8086 (16-bit)
● 80286 (chránený mód)
● 80386 (32-bitový chránený mód + množstvo
nových fičúr)
● X86-64
● Rozšírené inštrukčné sady: FPU (x87), MMX,
SSE, SSE2, SSE3, SSSE3, SSE4, SSE5, VMX,
SMX, SVM, AVX, XOP, ...
4. “Chrbtica” x86
CPU Northbridge Southbridge
Všetko ostatné
RAM Video RAM ŔOM
(nie naozaj)
5. Čo z toho pre nás vyplýva
● Procesor pristupuje k všetkým zariadeniam tým
istým mechanizmom (ako k RAM), nepotrebuje
zvláštne inštrukcie
● nie celkom pravda, ale pre náš účel užitočná
abstrakcia
● Nebudeme sa zaoberať “systémovými” a málo
používanými inštrukciami (segmentácia,
stránkovanie, task switching, stránkovanie, 16-
bit a real mód)
● Stačí nám zvládnuť základné operácie a prácu
s pamäťou
6. Inštrukcie
● Pokyny pre procesor (CPU) uložené v pamäti
● CPU ich číta a vykonáva
● Principiálne sa ničím nelíšia od bežných dát v
pamäti
● DOS program na riešenie sudoku (62 bytov):
B4 3F 8B D5 CD 21 91 43 88 02 4E 78 F7 B8 31 40
80 3A 2E 75 F5 8B F9 4F 60 78 ED 38 03 75 11 97
D4 13 6B C0 0B 96 43 7B F7 33 C6 A9 C0 E0 7E 02
F6 E4 61 70 E2 C6 02 2E 3C 39 74 F6 EB D1
8. “General purpose” registre
● Register = premenná procesoru
● CPU má množstvo registrov, 99.9% času sa ale pracuje s “general
purpose” registrami (GPR)
● V bežnej (?) reči preto “Register” = “General Purpose Register”
● x86 má 8 GPR (až x86-64 rozšírilo počet na 16)
● 8086 mal 16-bitové GPR registre:
AX, BX, CX, DX, SP, BP, SI, DI
● Možnosť pristupovať k 8-bit častiam prvých 4 registrov:
AL (low), AH (high), BL, BH, CL, CH, DL, DH
● 386 rozšíril na 32-bitov:
EAX, EBX, ECX, EDX, ESP, EBP, ESI, EDI
9. Špecializované využitie
“general purpose” registrov
0 = [E]AX = accumulator
1 = [E]CX = counter
2 = [E]DX = data
3 = [E]BX = base
4 = [E]SP = stack pointer
5 = [E]BP = base pointer
6 = [E]SI = source index
7 = [E]DI = destrination index
10. Formát x86 inštrukcie
● Prefix – voliteľný byte pred inštrukciou, menia
jej funkčnosť
● Mnemonics – udáva základnú operáciu ktorá sa
vykoná
● Operand – udáva register alebo pamäťovú
premennp, nad ktorou sa vykoná operácia.
Operandy môžu byť 0 až 3.
● Operandy musia byť rovnakej veľkosti
● Cieľový (destination) operand prvý
● Niektoré inštrukcie majú implicitný operand
12. Súčet / Rozdiel
ADD (addition)
add ebx, eax
add esp, 1
INC (increment, jeden operand)
inc eax
SUB (subtract)
sub ebp, 20
sub eax, ebx
DEC (decrement, jeden operand)
dec ecx
13. Bitové operácie
AND
and al, 11111100b
XOR
xor al, 101b
OR
or al, 100b
NOT (jeden operand)
not al
14. Negatívne čísla
● Čísla ktoré môžu nadobúdať aj zápornú hodnotu sa
nazývajú znamienkové
● Existuje niekoľko možností ako ich reprezentovať v
binárnej forme
● Najšikovnejší “two's complement”
● Tie isté operácie pre znamienkové aj
neznamienkové čísla
● Horný bit udáva znamienko
● Podtečenie: najmenšia hodnota – 1 = najväčšia
hodnota
● Pretečenie: najväčšia hodnota +1 = najväčšia
hodnota
16. Negatívne čísla
add eax, ebx
sub ecx, 5
add al, -1
add al, 255
sub al, 1
sub cl, -5
sub cl, 251
add cl, 5
17. Negácia čísla
NEG (negation) Bitwise spôsob
neg eax not eax
neg dx inc eax
neg cl
Napr.:
00000001 (1)
not
11111110 (-2)
+1
11111111 (-1)
18. Pamäť (z pohľadu CPU)
● Pole bytov
● Adresovaná 32-bitovým číslom, toto udáva
pozíciu (index) bytu v “poli”.
● Nieje možné pristupovať k dvom miestam v
pamäti vrámci jednej inštrukcie
● Zápis operandu pre prístup k pamäti v
assembleri:
[adresa] (adresa v hranatých zátvorkách)
20. Endianness
● Možnosť pristupovať k pamäti v rôznych veľkostiach
8-bit - byte
16-bit - word
32-bit - dword (double word)
64-bit - qword (quad word, X86-64 only)
● Poradie bytov vo väčších číslach od najmenej významného po
najviac významný (tzv. “little endian”)
● byty 00h, 01h = word 100h = word 100000000b = 256
● byty 11h, 22h, 33h, 44h = dword 44332211h
22. Nepriama adresácia pamäte
● Ako adresa môže byť použitá aj hodnota v
registri:
mov eax, dword [ebx]
mov al, byte [esi]
● K registru v adrese môže byť pripočítaná
konštanta
mov edx, dword [ebx+4]
mov al, byte [esi-1]
25. Príznaky
● CPU má register flags (korektne príznaky,
hovorovo flagy)
● Každý z jeho bitov má samostatný význam
● Nečítame ani nezapisujeme ho priamo
● Nastavuje sa podľa výsledku (nielen)
aritmetických inštrukcii
26. Príznaky
● CF (carry flag)
● Nastaví sa ak operácia pretečie ako celočíselná
● Inak využívaný inštrukciami ktoré “potrebujú nejaký
flag”
● OF (overflow flag)
● Nastaví sa ak operácia pretečie ako znamienková
● SF (sign flag)
● Nastaví sa ak je výsledkom operácie záporné číslo
(horný bit výsledku je 1)
● ZF (zero flag)
● Nastaví sa ak výsledok operácie je nula.
28. Podmienené skoky
● Skáču iba ak je splnená podmienka
JC (jump if carry) - CF=1
JNC (jump if not carry) - CF=0
JO (jump if overflow) - OF=1
JNO (jump if not overflow)- OF=0
JS (jump if signed) - SF=1
JNS (jump if not signed) - SF=0
JZ (jump if zero) - ZF=1
JNZ (jump if not zero) - ZF=0
29. Príklad:
Nulovanie 16 bytov
mov ecx, 16 ;nuluj 16 bytov
mov edi, 5 ;od adresy 5
nuluj:
mov byte [edi], 0 ;vynuluj byte na adrese EDI
inc edi ;posun EDI na dalsi byte
dec ecx ;dalsi byte hotovy
jnz nuluj ;ak je ecx>0, opakuj cyklus
30. CMP
● CMP (compare)
● Porovnáva dva operandy
● Nastaví flagy pre špeciálne skoky
● V skutočnosti SUB ktorý neprepíše cieľový register,
iba nastaví flagy podľa výsledku odpočítania.
● Príklady:
cmp eax, ebx
cmp eax, dword [4]
cmp byte [eax], dl
cmp ecx, 30
31. CMP pre neznamienkové čísla
● Podmienené skoky:
JB – jump if 1st operand below 2nd
JBE – jump if 1st operand below or equal to 2nd
JE – jump if 1st operand equal to 2nd
JAE – jump if 1st operand above or equal to 2nd
JA – jump if 1st operand above 2nd
● Pre každý z nich možno obrátiť podmienku: JN
(jump if not) namiesto J (jump if)
32. CMP pre znamienkové čísla
● Podmienené skoky:
JL – jump if 1st operand lower than 2nd
JLE – jump if 1st operand lower than or equal to 2nd
JE – jump if 1st operand equal to 2nd
JGE – jump if 1st operand greater than or equal to 2nd
JG – jump if 1st operand greater than 2nd
● Pre každý z nich možno obrátiť podmienku: JN
(jump if not) namiesto J (jump if)
33. Príklad #2
Nulovanie 16 bytov inak
mov ecx, 0
nuluj:
mov byte [ecx+5], 0 ;vynuluj ECX-ty byte od
;adresy 5
inc ecx ;dalsi byte hotovy
cmp ecx, 16 ;hotovych 16 bytov?
jne nuluj ;ak je ecx>0, opakuj cyklus
34. Príklad #3
Porovnanie reťazcov
mov esi, retazec1
mov edi, retazec2
porovnaj:
mov al, byte [esi] ;nacitaj znak prveho
cmp byte [edi], al ;porovnaj so znakom
;druheho
ja druhy_vacsi ;znak druheho vacsi?
jb prvy_vacsi ;znak druheho mensi?
inc esi ;ak su rovnake, posun
inc edi ;na dalsi znak
jmp porovnaj ;a repete
35. Čo je “assembler”?
● Program, ktorý prekladá symbolický zápis
inštrukcii na binárny strojový kód
● Syntax zápisu inštrukcii sa medzi rôznymi
assemblermi viac či menej odlišuje
● Z toho prenesene “assembler” ako označenie
niektorej konkrétnej syntaxe
● V širokom zmysle sa “assembler” používa aj
ako označenie ľubovolnej syntaxe ktorá
reprezentuje priamo strojový kód