ISU Cvičení 3 Marta Čudová Supercomputing Technologies Research Group Brno University of Technology, Faculty of Information Technology Božetěchova 1/2, 612 66 Brno - Královo Pole icudova@fit.vutbr.cz
Program v Assembleru 3 sekce section.data Deklarace a definice inicializovaných dat a konstant nemění se za běhu. ~ konstantní proměnné v C section.bss Deklarace proměnných (definice v programu), nemění se za běhu. Část paměti vyplněná nulami na začátku. section.text Návěští Kód, fixní velikost v paměti Pojmenování míst v paměti počítače Definice bodu v programu, na který lze skočit Lokální návěští je uvozeno znakem tečka a je platné jen mezi dvěma globálními návěštími section.data msg db 'Hello, world!', 0 section.bss var resb 10 section.text main: mov esi, msg call WriteString ret Marta Čudová - ISU, 3. cvičení 2
Registr 31 15 Bity 0 Pracujeme v 32-bitovém režimu. Každý ukazatel má 32 bitů. Marta Čudová - ISU, 3. cvičení 3
Univerzální registry Datové AX střádač, aritmetické operace, input/output BX bázový registr, adresování CX čítač, čítač v cyklech, posuvech a rotacích DX - input/output, aritmetické operace mul, div Segmentové CS (Code Segment) SS (Stack Segment) DS (Data Segment) ES (Extra Segment) Indexové a ukazatelé BP (Base Pointer) bázový registr SP (Stack Pointer) ukazatel vrcholu zásobníku DI (Destination Index) zdroj. index pro operaci s řetězci SI (Source Index) cíl. index pro operaci s řetězci Adresování paměti (data). Jejich obsah neměníme. Spoléháme, že jsou implicitně nastavené správně. Ukládají segmentovou část adresy. Pro práci se zásobníkem (lokální proměnné, parametry). Adresování paměti (data). Marta Čudová - ISU, 3. cvičení 4
(E)FLAGS Registr obsahuje 32 bitů (indikátorů), které procesor nastavuje podle výsledku právě provedené operace, a umožňuje tak větvit program. K registru nelze přistoupit jako k celku, ale lze přistoupit k jeho jednotlivým bitům (flagům). Některé bity jsou rezervované a nelze je měnit. Marta Čudová - ISU, 3. cvičení 5
EFLAGS Marta Čudová - ISU, 3. cvičení 6
Poznámky Registry EAX, ECX a EDX lze používat libovolně a není potřeba jejich hodnotu na konci funkce obnovovat. Registry EBX, ESI a EDI lze používat libovolně, na konci funkce je potřeba jejich hodnotu obnovit. Tyto registry mohou být využívány pro lokální proměnné. Registry ESP a EBP jsou používány pro práci se zásobníkem dle popsaného postupu. V registru FLAGS je potřeba vždy na konci funkce zajistit, aby hodnota bitu DF byla nastavena vždy na hodnotu 0. Marta Čudová - ISU, 3. cvičení 7
Inicializace paměti Datové typy: Byte Word (= 2B) Double word (= 4B) Quad word (= 8B) Několik příkladů: var_byte db 10 var_char_array db Ahoj, 0 var_dw_array dw 100, 150, 200 V.data sektoru definice dat (inicializace!) Definice proměnné var_byte o velikosti 1B a hodnotě 10. Definice polí. Více hodnot se oddělí čárkou = define word Všechny konstanty jsou lokální. Pro jejich zveřejnění je nutné použít klíčové slovo global. Marta Čudová - ISU, 3. cvičení 8
Inicializace paměti Datové typy: Byte Word (= 2B) Double word (= 4B) Quad word (= 8B) V.bss sektoru deklarace neinicializovaných dat proměnné Několik příkladů: byte_buffer resb 64 Rezervuj 64 bajtů pro proměnnou byte_buffer. word_buffer resw 1 Rezervuj 1 word. Marta Čudová - ISU, 3. cvičení 9
Adresování paměti Paměť lze indexovat pomocí: Přímé adresy (konkrétní pevná adresa) Nepřímé adresy (registry) Ukazatele přes bázový registr Ukazatel v index registru Pro získání dat z určité adresy nebo zápisu dat na danou adresu použijeme hranaté závorky [ ] Viz příklady na wiki Formát nepřímého adresování V 16b režimu: [ Bázový + Indexový + Konstanta ] V 32b režimu: [ Bázový + Indexový * Měřítko + Konstanta ] Index. registry SI, DI Pracujeme ve 32 bitovém režimu -> všechny adresy budou mít vždy 32 bitů! Bázové registry BX, BP Index. a bázové registry: EAX, EBX, ECX, EDX, ESI, EDI, EBP, ESP Měřítko: 1, 2, 4, 8 (byte, word, dword, qword) jak velká je lego kostka Marta Čudová - ISU, 3. cvičení 10
Cvičení v debuggeru Přímé adresování %include "rw32-2018.inc" section.data var1 dw 200 var2 dw 200,100 var3 db 7, 15, 155 section.text _main: Závorky => chci hodnotu! mov ax,[var1] ;použití konstantního ukazatele (symbolické adresy) mov bx,[var2+2] ;použití konstantního ukazatele (symbolické adresy) s offsetem mov cl,[var3] mov ch,[var3+1] mov dl,[var3+2] ret pole wordů 1 2 3 4 5 H e l l o! 0 C:pole[0] -> 1 pole[10] ->! Asm:[pole + 0] -> 1 [pole + 10] -> H [pole + 20] ->! C vytváří abstrakci, v Asm musíte velikost lego kostky znát sami! Marta Čudová - ISU, 3. cvičení 11
Cvičení v debuggeru Nepřímé adresování %include "rw32-2018.inc" section.data var dw 200 dw_array dw 200,100,300 dd_array dd 1, 1500, 2500, -5 section.text _main: mov ebx, dword 0 mov ax,[dw_array+ebx] Musím říct velikost! Je stejná jako velikost registru, do kterého cpu tu hodnotu. ;použití ukazatele + indexu přes bázový registr mov ax,[dw_array+ebx+2] ;použití ukazatele + indexu přes bázový registr + posun o konstantu mov esi, 2 mov eax, [dd_array+ebx] mov ecx, [dd_array+ebx+esi*4+4] ret Marta Čudová - ISU, 3. cvičení 12
Cvičení v debuggeru Ukazatel přes bázový registr %include "rw32-2018.inc"?? 1 5 10 15? section.data var dw 200 dw_array dw 200,100,300 db_array db 1, 5, 10, 15 mov ebx, db_array section.text _main: mov ebx, db_array ;Ukládáme adresu vždy 32bitů mov al, [ebx] ;Tady zohledňujeme velikost datového typu (byte -> 8 bitový registr) ret Úkol: Použijte pole dw_array (prvku typu word), adresu ukazující na druhou položku tohoto pole vložte instrukcí mov do vhodně velkého registru. Hodnotu této položky pak přesuňte do jiného registru, vhodné velikosti. Pozorujte v debuggeru. mov registr, adresa_proměnné mov registr, [hodnota_proměnné] Marta Čudová - ISU, 3. cvičení 13
Cvičení v debuggeru Ukazatel přes index registr %include "rw32-2018.inc" section.data db_string db ISU cviceni 3,0 section.text _main: mov esi, db_string ;Ukládáme adresu vždy 32bitů mov al, [esi+0] ;Přesun 8 bitové hodnoty z adresy uložené v registru call WriteChar ;Výpis hodnoty, funkce definovaná v rw32-2018.inc mov al, [esi+1] ;Přesun 8 bitové hodnoty z adresy uložené v registru esi posunuté o 1B do registru al call WriteChar ret Marta Čudová - ISU, 3. cvičení 14
Cvičení v debuggeru Zápis do paměti %include "rw32-2018.inc" section.data uk_char db '0123456789' uk_byte db 10h, 20h, 30h, 40h uk_word dw 1122h, 3344h, 5566h uk_dword dd 12345678h section.text _main: xor eax, eax ; eax = 0 xor ebx, ebx ; ebx = 0 mov [uk_byte], al ; [uk_byte + 0] = 0 mov [uk_word + ebx], ax mov edx, [uk_dword] mov ebx, uk_word mov [ebx], edx ; [uk_word] = 5678h ; [uk_word + 2] = 1234h ; konstanty (nutno definovat velikost zdrojového operandu) mov [uk_byte], byte 0ffh mov [ebx], byte 255 mov [ebx+1], word 1234h mov [ebx+3], dword 12345678h ret Marta Čudová - ISU, 3. cvičení 15
Little Endian vs. Big Endian Způsob ukládání dat do paměti pořadí bajtů Jeden ze základních zdrojů nekompatibility při ukládání a výměně dat v digitální podobě (např. přenos binárních souborů, síťová komunikace mezi různými platformami). Little-Endian Nejméně významný bajt (LSB) se uloží na paměťové místo s nejnižší adresou. Př. Procesory Intel Pentium Big-Endian Nejvíce významný bajt (MSB) se uloží na paměťové místo s nejnižší adresou. Marta Čudová - ISU, 3. cvičení 16
Pokud stihneme Kdyžtak probereme na dalším cvičení Marta Čudová - ISU, 3. cvičení 17
MOV, ADD, SUB MOV cíl, zdroj Přesune obsah zdrojového operandu do cílového MOV reg1,reg2 MOV [adr],reg MOV reg,[adr] MOV reg,konst MOV [adr], konst (MOVSX, MOVZX MOV se znaménkovým a bezznaménkovým rozšířením při přesunu dat z menšího do většího registru) ADD cíl, zdroj Přičte obsah zdrojového operandu k cílovému ADD reg1,reg2 ADD [adr],reg ADD reg,[adr] ADD reg, konst ADD [adr], konst SUB cíl, zdroj Odečte obsah zdrojového operandu od cílového SUB reg1,reg2 SUB [adr],reg SUB reg,[adr] SUB reg, konst SUB [adr],konst Marta Čudová - ISU, 3. cvičení 18
Několik zásad Velikost obou operandů musí být stejná (jen stejně velké lego kostky tvoří pár) Nelze použít dva paměťové operandy MOV adr, adr Pokud je jedním z operandů registr, pak určuje velikost Pokud ani jedním z operandů není registr, jeho velikost musí určit programátor pomocí datového typu (klíčová slova byte, word, dword) Marta Čudová - ISU, 3. cvičení 19
Zásobník Část paměti počítače vyhrazená k ukládání dat potřebných pro samotný chod programu. Slouží k: Ukládání hodnot registrů. Ukládání návratových adres funkcí při jejich volání Předávání parametrů ve vyšších programovacích jazycích. Ukládání lokálních proměnných. Princip LIFO. Na vrchol zásobníku ukazuje adresa uložená v ESP Na dno zásobníku ukazuje adresa uložená v EBP Přidáváním dat do zásobníku se ESP automaticky snižuje o velikost vkládaného registru nebo čísla a naopak. Marta Čudová - ISU, 3. cvičení 20
Zásobník Práce se zásobníkem: PUSH zdroj (obsah zdroje registr, paměť, hodnota se vloží na zásobník) POP cíl (ze zásobníku vlož do cíle registr, paměť) Velikost zásobníku je nastavena při sestavení programu. Pokud je dno nastavené na hodnotu 0xFF F, pak zásobník roste dolů k nižším adresám. 0 mpm nebo 1000 mnm 1000 mpm 0 mnm Marta Čudová - ISU, 3. cvičení 21
Díky za pozornost