Pouze tento týden sleva až 80 % na e-learning týkající se Pythonu
Aktuálně: Postihly zákazy tvou profesi? Poptávka po ajťácích prudce roste, využij podzimní akce 30% výuky zdarma!
Python týden

Lekce 5 - Assembler - Datové typy a proměnné

V minulé lekci, Assembler - ASCII tabulka a spuštění v DOSBox, jsme si vysvětlili ASCII tabulku, dokončili popis Hello world! programu a spustili si jej jako .com soubor v emulátoru DOSBox.

V dnešní lekci se budeme podrobněji věnovat datovým typům v ASM a samozřejmě proměnným.

Typový systém

Datové typy v ASM nejsou rozdělené klasicky podle toho, pro jaký typ obsahu jsou určeny. Každý z nás zná určitě Int, String nebo Boolean z vyšších programovacích jazyků, které potom ve finále zabíraly v paměti určitý počet bajtů. Překladač také kontroloval, zda jednotlivé datové typy všude sedí. V ASM definujeme rovnou kolik paměti se má pro určitou proměnnou vyhradit a již nikdo nekontroluje, co do tohoto prostoru potom ukládáme.

Definice proměnných v ASM

V minulých lekcí jsme si již proměnnou vytvářeli a také určili její datový typ. Bylo to u programu Hello world, kde proměnná hlwrld typu DB obsahovala text "Hello world!", končící ještě znaky pro konec řádku a řetězce:

hlwrld db "Hello, World!", 10, 13, 0

Proměnné v ASM tedy deklarujeme stylem: název typ hodnota. Z toho vyplývá, že DB je nějaký datový typ proměnné. Pojďme si tyto direktivy představit blíže.

Direktivy DB, DW a DD

V Assembleru nalezneme těchto pět typů proměnných, ale ve skutečnosti je to takový menší podvod. Jediný rozdíl je totiž jejich velikost. V této tabulce jsou direktivy a jejich velikosti:

Direktiva Celý název Velikost Rozsah
DB Define Byte 1 bajt -128 až 255
DW Define Word 2 bajty -32768 až 65535
DD Define Doubleword 4 bajty -2147483648 až 4294967295
DQ Define Quadword 8 bajtů Příliš velká čísla
DT Define Ten Bytes 10 bajtů Příliš velká čísla

Nenechte se zmást slovem "Word", nejedná se o nic ve spojitosti se slovem nebo textem, ale pouze o termín určující velikost 2 bajty.

U direktiv define (to jsou všechny v tabulce uvedené) musíme proměnnou zároveň také inicializovat. Pro práci s neinicializovanými proměnnými se používají pak zas jiné direktivy.

Uložení čísla do proměnné

Číslo do proměnné v Assembleru uložíme velmi jednoduše, pouze určíme velikost v bajtech pomocí příslušné direktivy:

male_cislo DW 15
cislo DW 23093
negativni_cislo DW -23093
vetsi_cislo DD 342183449
desetinne_cislo DD 1.552
desetinne_cislo2 DQ 123.456

Negativní čísla se ukládají jako dvojkové doplňky. Pro vícebajtové hodnoty procesor používá malou endianitu. Pokud vám tyto pojmy nic neříkají, jsou vysvětleny v kurzu Principy fungování počítačů.

Uložení řetězce do proměnné

Jak je ale možné, že do proměnné velikosti 1 byte můžeme uložit libovolně dlouhý textový řetězec? Při použití řetězce v uvozovkách nebo apostrofech '' v direktivě DB se pro každé písmeno samozřejmě vyhradí jeden bajt. Tento kód:

hlwrld db "Hello, World!", 10, 13, 0
Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!

Je vlastně jen zkrácený zápis:

hlwrld db "H", "e", "l", "l", "o", ",", " ", "W", "o", "r", "l", "d", "!", 10, 13, 0

Což je zkrácený zápis z:

hlwrld db "H"
       db "e"
       db "l"
       db "l"
       db "o"
       db ","
       db " "
       db "W"
       db "o"
       db "r"
       db "l"
       db "d"
       db "!"
       db 10
       db 13
       db 0

Doplnění řetězce na násobky bajtů

Možná vás napadlo, co by se stalo, kdybychom proměnnou s řetězcem definovali namísto DB např. pomocí DW nebo dalšími direktivami pro větší datové typy. Fungovalo by to, ale výsledek by vždy zabíral násobek počtu bajtů daného datového typu (např. v případě DW násobek 2) a text by byl na konci doplněný nulovými znaky, aby měl požadovanou délku. Např. text "ABCDEF" by byl při deklaraci jako:

text dd 'ABCDE'

uložený jako:

0x41 0x42 0x43 0x44 0x45 0x00 0x00 0x00

(tedy jako 8 bajtů, což jsou 2 doubleword)

Ale co ta divná čísla? Hodnoty bajtů v paměti většinou vypisujeme jako hexadecimální čísla, protože je tento zápis kratší. Kromě písmena H se čísla v šestnáctkové soustavě označují někdy také jako 0x. Již víme, že ASCII kód znaku A je 65 a vidíme, že první bajt má hodnotu 0x41, kde 41 hex je opravdu 65 dec a tedy znak A.

Jako řetězec můžeme uložit např. i znak "y"/"n" pro reprezentaci volby uživatele:

znovu DB 'y'

Proměnné a registry

Teď již víme, jak proměnné deklarovat a jaké jsou velikosti jednotlivých typů. Nyní si ukážeme, jak se dají proměnné kombinovat s registry a mezi sebou.

Stejně jako u registru je důležité dodržovat velikost. Zde jsou příklady pro kombinaci s registry pro překladač NASM.

S 8bitovým registrem:

; s 8bitovým registrem
mov byte [value], al ; Do proměnné value přesuneme hodnotu z registru AL.
mov al, byte [value] ; Do registru AL přesuneme hodnotu z proměnné value.

value db 0           ; Definujeme proměnnou value.

S 16bitovým registrem:

; s 16bitovým registrem
mov word [value], ax ; Do proměnné value přesuneme hodnotu z registru AX.
mov ax, word [value] ; Do registru AX přesuneme hodnotu z proměnné value.

value dw 0           ; Definujeme proměnnou value

Přiřazení z proměnné do proměnné

Pokud chceme přenést hodnotu z jedné proměnné do druhé, musíme použít registr:

; přenesení hodnoty z jedné proměnné do druhé
mov al, byte [value1] ; Do registru AL přesuneme hodnotu z proměnné value1
mov byte [value2], al ; Do proměnné value2 přesuneme hodnotu z registru AL

value1 db 0           ; Proměnná value1
value2 db 0           ; Proměnná value2

Takto bychom pracovali s číselnými hodnotami, ale jak se to dělá s textem?

Ukazovací registry

Pokud chceme pracovat s textem, je dobré naučit se pracovat s ukazovacími registry. Ty spadají pod univerzální registry a patří sem registry DI a SI. Pro "čtení" textu se používá SI a pro nějaké úpravy DI. Oba dva registry jsou 16bitové. Již jsme se s nimi setkali v lekci o programu Hello world.

Registr SI (Source Index)

Registr SI je ukazatel na zdrojová data při kopírovacích operacích.

Registr DI (Destination Index)

Registr DI je ukazatel na cílová data při kopírovacích operacích.

Zde je kód k programu nazvanému Písmenka. Program "analyzuje" větu v proměnné veta a vybere z ní písmenka "a", která přesune do proměnné pismenka. Pracuje se zde jak s registrem DI, tak s registrem SI. Kód je napsaný pro emulátor EMU8086, který najdete v příloze spolu s kódem:

org 100h

main:
mov di, [pismenka]                      ; Nastavíme registr DI na proměnnou pismenka
mov si, [veta]                          ; Nastavíme registr SI na proměnnou veta

get_char:
lodsb                                   ; Načteme znak z proměnné veta do registru AL
cmp al, 'a'                             ; Pokud je znak 'a'...
jz add_char                             ; ...skoč na add_char
cmp al, 0                               ; Pokud je číslo znaku 0 (null)...
jz continue                             ; ...skoč na continue
jmp get_char

add_char:
mov byte [di], al                       ; Přesuneme znak do registru DI (do proměnné pismenka, namísto registru AL můžeme napsat i 'a') a...
inc di                                  ; ...posuneme se na další místo v proměnné
jmp get_char

continue:
mov byte [di], 0                        ; Do registru DI (do proměnné pismenka) přesuneme číslo 0 (null)

mov si, [pismenka]                      ; Nastavíme registr SI na proměnnou pismenka

print:
lodsb                                   ; Načteme znak z proměnné pismenka do registru AL
cmp al, 0                               ; Pokud je číslo znaku 0 (null)...
jz return                               ; ...skoč na return
mov ah, 0eh                             ; Funkce BIOSu pro teletypový výstup
mov bx, 7h
int 10h                                 ; Vypiš znak
jmp print

return:
ret                                     ; Vrať kontrolu operačnímu systému

veta: db "Ahoj, jak se mas, Karle?", 0  ; Proměnná veta
pismenka: db 0                          ; Proměnná pismenka

Můžete si všimnout, jak se s takovými ukazovacími registry pracuje. Tady je jednodušší příklad:

mov di, [text]
mov byte [di], 97
inc di
mov byte [di], 98
inc di
mov byte [di], 99
inc di
mov byte [di], 0

mov si, text
print_string:
lodsb
or al, al
jz short end
mov ah, 0eh
mov bx, 7h
int 10h
jmp print_string
end:
ret

text: db 0

Přesunutím proměnné text do registru DI řekneme registru, na co má ukazovat. Následovně nastavíme první znak na "a", instrukcí INC posuneme ukazatel na další znak, kam zapíšeme "b" a tak dále...

Instrukce INC (Increment)

Instrukce INC má jeden parametr a tím může být registr nebo proměnná. Z anglického increment vyplývá, že instrukce má za úkol "přičíst číslo jedna" buď do registru, nebo do proměnné.

V příští lekci, Assembler - Instrukce pro práci s čísly, si probereme instrukce pro práci s čísly.


 

Stáhnout

Staženo 33x (2.68 MB)

 

Předchozí článek
Assembler - ASCII tabulka a spuštění v DOSBox
Všechny články v sekci
Assembler
Článek pro vás napsal Jakub Verner
Avatar
Jak se ti líbí článek?
1 hlasů
Autor se věnuje programování v Assembleru a v C#. Rád se zlepšuje, rozšiřuje si znalosti a věří, že když člověk chce, dokáže cokoliv.
Aktivity (4)

 

 

Komentáře

Avatar
Jakub A. Štigler:3. července 15:07

Neměl by v tabulce být jeden byte 0 až 255 nebo -127 až 127 místo -128 až 255 (a ostatní hodnoty stejným způsobem)?

Editováno 3. července 15:09
 
Odpovědět
3. července 15:07
Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!
Avatar
Jakub Verner
Redaktor
Avatar
Odpovídá na Jakub A. Štigler
Jakub Verner:15. července 3:46

Ahoj, v Assembleru existuje BYTE (0 - 255), ale také SBYTE - SIGNED BYTE (-128 - 127). Oba dva se definují pomocí zkratky DB. Svým způsobem máš tedy pravdu, ale celkový číselný rozsah pro zkratku DB je tedy -128 - 255. Vlastně jsme jenom BYTE a SBYTE spojili dohromady pod jednu zkratku. U WORDu a ostatních je to to samé. Díky za komentář. :-)

Editováno 15. července 3:48
 
Odpovědět
15. července 3:46
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 2 zpráv z 2.