Zarábaj až 6 000 € mesačne! Akreditované rekvalifikačné kurzy od 0 €. Viac informácií.

1. diel - Úvod do programovania v Assemblera

Vitajte u kurzu, v ktorom sa spolu ponoríme až do hĺbok, kam sa vôbec ako programátori môžeme dostať. Obídeme programovací jazyk aj kompiler a zistíme, ako funguje samotný stroj. Budeme posielať priamo inštrukcie procesora, pochopíme architektúru x86, BIOS, ako sa adresuje pamäť a zavádza operačný systém. Táto problematika súvisí aj s reverse-engineering, crackováním softvéru a samozrejme hackingom. Naučí vás používať nástroje ako disassembler, cheat enginy a lepšie pracovať s debuggery.

hacking - Assembler

Kurz zahájme slávnu citácií:

Nechcem learn to hack, hack to learn!

Predpoklady

Kurz predpokladá znalosť aspoň základov fungovania počítača po hardvérovej stránke a skúsenosť s ľubovoľným vysokoúrovňovým programovacím jazykom (napr. C alebo Java).

Prečo sa dnes učiť Assembler?

Vždy ma zaujímalo, ako veci v základe fungujú a namiesto toho, aby som používal niečo, čo už existuje, som si radšej urobil niečo svoje. Napríklad máme doma rádio. A ja, namiesto toho, aby som ho používal, začal som sa stavbou vlastného AM rádia. A alebo väčšina z nás používa operačný systém Windows ... No a čo som asi urobil ... Áno, začal som pracovať na vlastnom operačnom systéme v Assemblera.

Čo sa tu budeme učiť je samozrejme veľmi špeciálna a úzke zameranie. Komerčne dnes tieto znalosti uplatníte vo sfére kyberbezpečnosti alebo pri programovaní pre niektoré nízkej odozvy embedded zariadenia, prípadne pre high-performance programovanie. A alebo keď sa budete chcieť pokúsiť donútiť robiť nejakú cudziu aplikáciu to, čo od nej chcete, prípadne si naprogramovať zavádzač operačného systému. To samozrejme nie je tak ľahké, ale niekde sa začať musí:)

Aby sme pochopili ako vôbec ASM funguje, pozrime sa v skratke na históriu programovacích jazykov.

Vývoj programovacích jazykov

1. generácie jazykov - Strojový kód

Procesor počítača vie vykonávať len obmedzené množstvo jednoduchých inštrukcií, ktoré sú uložené ako sekvencie bitov, sú to teda čísla. Tá sa mu zvyčajne zadávajú v hexadecimálne (šestnástkovej) sústave. Inštrukcie sú tak elementárne, že umožňujú iba napr. Prácu s registrami procesora (to je pamäť v CPU) alebo skoky. Nemožno napr. Jednoducho sčítať dve čísla, musíme sa na čísla pozerať ako na adresy v pamäti a také sčítaní čísel zaberie niekoľko inštrukcií. Program sčítající dve čísla by vyzeral napr. Takto:

2104
1105
3106
7001
0053
FFFE
0000

Inštrukcie sa procesora predloží v binárnej podobe. Takýto kód je samozrejme extrémne nečitateľný a závisí na inštrukčnú sade daného CPU. Každý počítačový program musí byť nakoniec do tohto jazyka preložený, aby mohol byť na procesore počítača spustený.

strojový kód - Assembler

2. generácia jazykov - Assembler

Assembler čiže JSA (jazyk symbolických inštrukcií) sa objavil niekedy v polovici 20. storočia. Konkrétne sa jednalo o jazyk druhej generácie. Od jazykov prvej generácie sa líšil tým, že namiesto toho, aby sme si museli pamätať číselné kódy inštrukcií, sme mohli písať ich slovné kódy (napríklad: MOV, CMP, ADD).

Vďaka Assemblera bolo písanie programov jednoduchšie a prehľadnejšie, než keby sme ich písali v číslach. Ďalšou výhodou bolo, že adresy v programe sa nemuseli meniť prepisovaním celého programu ako tomu bolo u prvej generácie. Čo sa týka kódu samotného, nemuseli sa opäť napr. Zložito vypočítavať adresy skokov. Kód teda začal byť vôbec ľudsky čitateľný, aj keď nie je o nič jednoduchšie, než pôvodný strojový kód.

Rovnaký program by v ASM vyzeral takto:

ORG 100
LDA A
ADD B
STA C
HLT
DEC 83
DEC –2
DEC 0
END

Vidíme, že je to trochu ľudskejší, ale stále nezainteresovaní ľudia vôbec netušia, ako program funguje.

3. generácie jazykov

Jazyky v tretej generácii konečne ponúka užívateľovi určitú abstrakciu nad tým, ako program vidí počítač, zameriavajú sa na to, ako program vidí človek. Sú označované ako tzv. Vyššej programovacie jazyky (anglicky High Level Languages, niekedy skrátene HLL). Naše čísla sú vnímaná už ako premenné, zdrojový kód pripomína matematický zápis.

Jedným z prvých vysokoúrovňových programovacích jazykov bol jazyk C. Aj keď ho predbehol Fortran alebo Pascal, tak to bol práve jazyk C, ktorý dobyl svet. Opäť ten istý programy by v jazyku C vyzeral takto:

int main(void)
{
    int a, b, c;
    a = 83;
    b = -2;
    c = a + b;
    return 0;
}

V kontraste súčasných objektovo orientovaných moderných jazykov je jazyk C často označovaný ako jazyk nízkoúrovňový. Ako to teda je? Od príchodu jazyka C skrátka ubehlo už niekoľko dekád a záleží s čím ho porovnávame. V našom kontexte s ASM je nazývaný vysokoúrovňovým, v kontexte napr. S jazykom C # .NET je naopak nízkoúrovňový.

Všetci asi tušíme, čo program robí, spočíta čísla 83 a -2 a výsledok uloží do premennej c. U všetkých jazykov tretej generácie je samozrejme výhodou vysoká čitateľnosť.

Preklad vyšších jazykov do assembleri

Tieto jazyky teda majú svoj zdrojový kód v jazyku, ktorému ľudia dobre rozumie. Zdrojový kód sa samozrejme musí preložiť do binárneho kódu, aby ho bolo možné na procesore spustiť. Tento preklad zaisťuje prekladač (kompiler), ktorý preloží naraz celý program do assembleri.

Kompiler - Assembler

Ak budeme vedieť, ako vyzerajú v ASM rutiny napr. C prekladača, budeme schopní pochopiť, ako tieto programy fungujú alebo ich dokonca modifikovať, bez toho aby sme od nich mali zdrojový kód. Jedná sa ale samozrejme o veľmi komplexnú problematiku, pretože sebemenší funkcie vyústi vo veľké množstvo ASM inštrukcií a kompiler vo výslednej podobe ešte vykonáva početné optimalizácie. Poďme im venovať aspoň krátky odsek.

Optimalizácia prekladače

Keď by sme písali v čistom ASM, veľmi pravdepodobne bude náš program pomalší ako ten istý program skompilovaný napr. Z jazyka C. Ako je to možné? Kompiler totiž kód upraví tak, aby bol veľmi rýchly a to často za cenu, že je pre človeka potom zle čitateľný. Určite ste všetci niekedy použili cyklus. Ten má nejakú riadiacu premennú, podmienku a skrátka réžii navyše. Preto sa môže niekedy optimizer rozhodnúť, že bude lepšie cyklus nepřeložit, ale namiesto toho kód len niekoľkokrát zopakovať za sebou. Ak vás problematika zaujíma, odporúčam krásny článok Prekladača pod pokrievkou - optimalizácia.

Špecifiká programovanie v Assemblera

A ako teda také programovanie bez prekladača vyzerá?

Všeobecne v Assemblera (ASM) neexistujú vopred vytvorené funkcie - Nenájdeme tu žiadne PrintString(), ClearScreen(), ani SetCursorPosition(). Všetko si musíme vytvoriť sami. Ak nám beží v mašine nejaká nadstavba (napr. Operačný systém), môžeme samozrejme volať z ASM jeho API, ale tým už nepracujeme len čisto s inštrukčnou sadou a prerušeniami BIOSu.

Ešte by som rád na úvod na niečo upozornil! Je možné, že poznáte prerušenie INT 21H (k prerušením sa v kurze čoskoro dostaneme). Toto prerušenie je dostupné iba v operačnom systéme MS-DOS, čo znamená, že ho (ani ostatné) nebudeme používať. My si vystačíme s prerušeniami, ktorá ponúka BIOS.

Ukážka kódu

Na záver úvodného dielu si ukážeme a popíšeme zdrojový kód metódy PrintString pre výpis textu len pomocou rutín BIOSu. Metódu budeme používať nabudúce, kde si ju tiež vysvetlíme. Tu sa na ňu môžete pozrieť len preto, aby ste vedeli, ako programovanie v ASM vyzerá a do čoho sa to vlastne púšťame.

Metóda PrintString:

PrintString:    ; Začátek metody pro vypisování zprávy
lodsb           ; Přesuneme řetězec do registru AX
or al, al       ; Zkontrolujeme, jestli je v registru AL ještě nějaký znak, který bychom mohli vytisknout
jz short .Done  ; Pokud ne, skočíme na .Done
mov ah, 0eh     ; Registr AH naplníme hodnotou 0eh
mov bx, 7h      ; Registr BX naplníme hodnotou 7h
int 10h         ; Vytiskneme znak
jmp PrintString ; Vrátíme se na začátek metody
.Done:          ; Popisek pro návrat
ret             ; Vrátíme se na místo, odkud jsme metodu zavolali

No a to je pre dnešok všetko.

V budúcej lekcii, Assembler - Vytvorenie NASM projektu, registre a prerušenie , si založíme ASM projekt a povieme si čo sú to registre a prerušenia.


 

Všetky články v sekcii
Assembler
Preskočiť článok
(neodporúčame)
Assembler - Vytvorenie NASM projektu, registre a prerušenie
Článok pre vás napísal Jakub Verner
Avatar
Užívateľské hodnotenie:
1 hlasov
Autor se věnuje programování v x86 Assembleru.
Aktivity