Katolícka univerzita v Ružomberku Pedagogická fakulta programovací jazyk ASSEMBLER 1. ročník IN-FY
Na úvod Pracovať priamo so zdrojovým kódom je pre človeka veľmi zložité, pretože programy v strojovom kóde sú postupnosťami veľmi komplikovane formátovaných čísel. Preto bolo potrebné vytvoriť jazyk, ktorý by bol zrozumiteľný pre človeka a zároveň by bol transformovateľný do strojového kódu. Assembler jazyk symbolických adries je programovací jazyk, v ktorom každý kód inštrukcie generuje jednu inštrukciu strojového jazyka, viazanú na konkrétny procesor počítača (napríklad v Céčku sa kódový príkaz už neviaže na konkrétny počítač alebo operačný systém). Jazyk nízkej úrovne znamená, že assembler pracuje priamo len so štandardnými dátovými typmi ako sú znaky, celé a reálne čísla, pomocou ktorých možno skontrolovať fungovanie styku počítača s prostredím. Základné pojmy Inštrukcia procesoru základný prvok činnosti, ktorú vykonáva procesor (Central Processor Unit). Register (register procesoru) malá pamäťová oblasť umiestnená vo vnútri procesoru, v mieste s najrýchlejším prístupom procesoru k pamäti. Register je pomenovaný a je veľmi malý možno do neho uložiť obvykle len niekoľko bitov informácií. Je používaný ako dočasný pamäťový priestor pre rozpracované medzi výsledky operácií. Adresa celé číslo, ukazujúce na miesto v pamäti Prerušenie je udalosť, pri ktorej procesor prestane vykonávať inštrukcie práve vykonávaného programu a dočasne začne vykonávať program iný, obsluhujúci prerušenie ALU (aritmeticko logická jednotka) Vykonáva operácie spojené so spracovaním dát: matematické, logické a posuvy (rotácie). Pamäť (memory) zariadenie umožňujúce uchovať informácie (konkrétne binárne kódovaných dát). Adresa v pamäti číselné označenie miesta v pamäti Radič zariadenie prevádzajúce príkazy v symbolickej forme (inštrukcii) na postupnosť signálov ovládajúcich pripojene zariadenie Strana č.: 1
Dátové typy Základnou a ďalej nedeliteľnou jednotkou informácie je jeden bit je odvodený z anglického slova BInary digit binárna číslica. V dvojkovej (binárnej) sústave môže číslica nadobúdať iba hodnotu 0 alebo 1, ide o elementárne rozhranie stavu pravda nepravda, vypnuté zapnuté. Na dvojkovej logike sú postavené všetky logické obvody a z logických zase počítač. Jeden bit je zároveň najmenšie množstvo informácie, ktorú môže z pamäti prečítať alebo do pamäti zapísať. V jednom byte môžeme uložiť číslo 0 255 (2 8 = 256 rôznych čísel). Ak nestačí tento rozsah, môžeme použiť slovo, ktoré má rozsah 0 65535 (2 16 = 65536 čísel), alebo dvoj slovo s rozsahom 0 4294967295 (2 32 = 4294967256 rôznych čísel). Bity čísla môžeme zoskupovať. Obr. 1.: Skupina štyroch bitov sa nazýva nibble alebo pol slovo (húsenica). H.O. high order (vyššie poradie), L.O. low order (nižšie poradie) Počítač nepracuje s jednotlivými bitmi, ale s ich skupinami, napr.: osem bitov tvorí elementárny dátový typ, označovaný ako byte (slabika). Prečo práve osem? Odpoveď hľadajme u vývojárov firmy IBM, ktorý projektovali prvé počítače. Ďalej môžeme zoskupovať a vytvárať slovo (word), dvoj slovo (dword): 1 byte = 8 bitov 1 word = 2 byte = 16 bitov 1 dword = 4 byte = 32 bitov Strana č.: 2
Mikroprocesor 80386 Mikroprocesor 80386 je plne tridsaťdva bitový, čo znamená, že môže pracovať až s 4 GB operačnej pamäte (2 32 byte). Keďže je aj zbernica tridsaťdva bitová, môže procesor spracovávať alebo ukladať vo svojich registroch taktiež číslo (dáta) o šírke tridsaťdva bitov (odpovedá typu LongInt v programovacom jazyku Pascal). Aby sme mohli programovať v Assemblery, musíme poznať registre. Obr. 2.: Registre 80386 Registre EAX, EBX, ECX, EDX - patria do skupiny univerzálnych registrov - možno ho rozdeliť na horných šestnásť bitový register AX, BX, CX, DX a na dolný, ktorý je nepomenovaný. Horné registre možno rozdeliť na podmnožiny na dva osem bitové registre, ktoré sa volajú AL AH, BL BH, CL CH, DL DH. Registre EBP, ESP, EIP - patria do skupiny ukazovacích registrov ESP (SP) - je ukazovateľom na pamäť, kde je uložený vrchol zásobníku. EIP (IP, instruction pointer) ukazuje do pamäti na inštrukciu, ktorá sa bude spracovávať ako nasledujúca. Tento register mení priamo radič mikroprocesoru podľa toho, ako vyberá inštrukcie z pamäti. Strana č.: 3
Registre ESI, EDI - patria do skupiny indexových registrov SI source index DI destination index - možno ich využiť k uloženiu nejakých dát, nikto nám nezakazuje, že musí skutočne obsahovať nejakú adresu Registre DS, GS, FS, SS, CS, ES - patria do skupiny segmentových registrov, ktoré sa podieľajú na výpočte skutočnej adresy (adresy, ktorá sa bude vysielať po adresovej zbernici). Registre príznaku EFLAGS - Obsahuje jednotlivé príznaky (vlajky) indikujúce prevažne stav atitmeticko logickej jednotky mikroprocesoru. Inštrukcie Assembleru Program je tvorený dvoma druhmi kľúčových slov: - Direktívami - nevytvárajú kód programu, alebo riadi činnosti prekladača - Inštrukciami - sú symbolickým zápisom strojových inštrukcií procesoru Syntax zápisu inštrukcie: návestie inštrukcia cieľ, zdroj ;komentár Cieľ a Zdroj sú operandami inštrukcie. Operand môže byť register, konštanta, pamäťové miesto. Komentár je ľubovolný text, oddelený od inštrukcie bodkočiarkou. Návestie je symbolické meno, ktoré označuje offset v danom registre. Návestie môže byť blízke (NEAR) alebo vzdialené (FAR). Návestie je v podstate identifikátor ukončený dvojbodkou, ktorému bola pri preklade pridelená adresa podľa miesta výskytu programu. Ak nieje typ skoku určený, predpokladá sa typ NEAR. Strana č.: 4
Niektoré základné inštrukcie Inštrukcia MOV Syntax: MOV cieľ, zdroj Slúži k presunom, kopírovaniu zdrojového operandu do cieľového. Všetky operandy inštrukcie mov musia mať rovnakú veľkosť. mov ax, [cislo] ;do registru ax vloží hodnotu premennej cislo mov [cislo], ax ;do premennej cislo vloží hodnotu register ax mov bx, cx ;do registru bx vloží hodnotu registru cx mov al, 1 ;do registru al vloží konštantu 1 mov ax, 0 ;vynuluje register ax (al aj ah) Aritmetická inštrukcia ADD Syntax: ADD o1, o2 Sčíta oba operandy a výsledok uloží do operandu o1, jeho predchádzajúca hodnota je stratená. mov ax, 5 ;do registru ax vloží 8 mov cx, 10 ;do registru cx vloží 10 add cx, ax ;sčíta cx + ax = cx Aritmetická inštrukcia SUB Syntax: SUB o1, o2 Odčíta o1 o2 a výsledok sa uloží do o1; jeho pôvodná hodnota sa stratí. add eax, 10 ;k registru eax pripočíta 8 sub ecx, ebp ;register ebp ecx = ecx sub ah, al ;od registru ah odčíta al a výsledok uloží do ;ah Strana č.: 5
Aritmetická inštrukcia INC a DEC Syntax: INC o1 ;o1 = o1 + 1 DEC o1 ;o1 = o1-1 Inštrukcia pripočítava (INC) alebo odpočítava (DEC) jediný operand o jednotku. add al, 1 inc al dec dx inc word [cislo] ;správne ale požiadavku možno ;splniť aj takto ;odčítame 1 od hodnoty registru dx ;pripočítame 1 do šestnásťbitovej premennej ;číslo, napovedali sme rozsah (0-65535, tj. 16 ;bitov) Aritmetická inštrukcia MUL a DIV Syntax: MUL r/m8/16/32 DIV r/m8/16/32 Inštrukcia MUL (multiply) slúži na násobenie, DIV (divide) slúži na delenie. Aby nebola inštrukcia MUL a DIV príliš zložitá, bolo rozhodnuté, že jeden operand a výsledok bude uložený v (rovnakom) pevne danom registre. Umiestnenie druhého operandu bolo ponechané na programátorovi. mov al, bh ;register bh nahrá do al mul cl ;vynásobí al s cl, výsledok bude uložený v ax ; - mov ax, 25 ;do ax vložíme 25 mov cl, 5 ;do cl vložíme 5 div cl ;vydelíme cl (ax / cl = výsl. (v registru ax)) mov bx, ax ;výsledok prekopírujeme do bx Strana č.: 6
Inštrukcie nepodmieneného skoku JMP Syntax: JMP typ_skoku o1 Inštrukcia JMP prinúti procesor spracovávať inštrukcie z iného miesta v pamäti. Nepodmienený skok poznáme s vyšších programovacích jazykov pod názvom GOTO v assemblery ho predstavuje skok JMP. mov ax, 4 ;do ax vložíme hodnotu 4 novy_cyklus: ;návestie s názvom novy_cyklus mov bx, ax ;do bx vložíme hodnotu ax jmp novy_cyklus ;skok na novy_cyklus, typ skoku v tomto ;prípade je predpokladaný typ NEAR Inštrukcie podmieneného skoku Jx Syntax: Jx navestie_cielu_skoku Inštrukcie podmieneného skoku existuje celá rada. Navzájom sa odlišujú rozhodujúcou podmienkou, ktorá riadi prevedenie skoku. V závislosti na vyhodnotenej podmienke sa vykonávanie programu buď presunie na iné miesto alebo program pokračuje na nasledujúcej adrese za inštrukciou skoku. Rozhodujúcou podmienkou sú stavy príznakov (vlajok). Príklad najpoužívanejších skokov: jz slnene jc splnene js splnene jo splnene... ;skočí, ak je príznak ZF (príznak nuly) ;nastavený na 1 ;skočí, ak je príznak CF (príznak prenosu) ;nastavený na 1 ;skočí, ak je príznak SF (príznak znamienka) ;skočí, ak je príznak OF (príznak pretečenia) Strana č.: 7
Konštrukcie cyklov V assembleru vykonávame cykly pomocou inštrukcií podmieneného, nepodmieneného skoku, inštrukcií porovnania (CMP, TEST). S ním sme schopní implementovať aj príkaz opakovania FOR. for_start: mov ecx, 0 ;naplníme register ecx nulou for_cyklus: ;na toto návestie sa budeme vracať... ;tu sa budú vykonávať príkazy pod cyklom FOR inc ecx ;ecx zvýšime o 1 cmp ecx, 10 ;porovnáme ecx s 10 jnz for_cyklus ;ak nieje 10, skočím na for_cyklus (skočí vždy ;pokiaľ sa nerovnajú) for_skonci: ;ak je 10, skočí na for_skonci Strana č.: 8
(* Príklad použitia implementácie jazyka Assembler v jazyku Pascal *) Program ASM_v_Pascale; Uses Crt; Var cislo1,cislo2:integer; scitanie,odcitanie,nasobenie,delenie:integer; Begin ClrScr; Writeln('program s pouzitim assembleru'); cislo1:=0;cislo2:=0;scitanie:=0; Writeln('zadaj dva cisla');readln(cislo1,cislo2); Asm mov dx,cislo1 add dx,cislo2 mov scitanie,dx mov cx,cislo1 sub cx,cislo2 mov odcitanie,cx mov ax,cislo1 mul cislo2 mov nasobenie,ax mov ax,cislo1 div cislo2 mov delenie,ax End; Writeln; Writeln(cislo1,' + ',cislo2,' = ',scitanie); Writeln(cislo1,' - ',cislo2,' = ',odcitanie); Writeln(cislo1,' * ',cislo2,' = ',nasobenie); Writeln(cislo1,' / ',cislo2,' = ',delenie); Repeat Until KeyPressed; End. Strana č.: 9
Program kurzor_v_pascale; Uses Crt; Var x,y:integer; begin ClrScr; Repeat Asm mov Ax,1 int 33h mov Ax,3 mov X,Cx int 33h mov Ax,3 mov Y,Dx int 33h End; Until KeyPressed; End. Strana č.: 10