Uvod v Assembly
Assembly je nizkostopenjski jezik, ki se uporablja za programiranje računalniških sistemov. Je neposredno povezan z arhitekturo procesorja in omogoča programerju natančen nadzor nad strojno opremo. Assembly je zapisan v obliki nabora ukazov (opcodes), ki jih procesor lahko neposredno izvaja.
V nasprotju s programskimi jeziki višje ravni, kot je na primer C ali Python, ki se pogosto uporabljajo za razvoj aplikacij, je assembly bolj osredotočen na neposredno manipulacijo s pomnilnikom, registri in drugimi strojnimi viri. Programerji, ki pišejo v assemblyju, imajo popoln nadzor nad vsakim korakom izvajanja programa, kar jim omogoča optimizacijo delovanja in natančno prilagajanje potrebam sistema.
Za razliko od visokoravnijskih jezikov, ki uporabljajo razumljive simbole in izraze, je assembly nizko nivojski jezik, ki se izraža z mnemoničnimi oznakami za posamezne ukaze, kot so "mov" (premik podatkov), "add" (seštevanje) ali "jmp" (skok). Te mnemonične oznake se nato pretvorijo v strojno kodo, ki jo procesor lahko izvaja.
Pisanje v assemblyju zahteva temeljno razumevanje arhitekture procesorja, registrov, pomnilnika in načinov delovanja ukazov. Kljub temu, da je pisanje v assemblyju običajno bolj zapleteno in zahtevno kot v višje ravni jezikih, ima prednosti, kot so večja učinkovitost, boljši nadzor nad strojno opremo in možnost izvajanja kritičnih operacij, ki jih je težje doseči z višje ravni jeziki.
Registri
- Splošni namenski registri (General Purpose Registers):
- EAX (Accumulator Register): Uporablja se za aritmetične operacije, shranjevanje rezultatov in prenašanje parametrov funkcij.
- EBX (Base Register): Uporablja se za indeksiranje pomnilnika in kot kazalec na podatke.
- ECX (Counter Register): Pogosto se uporablja kot števec v zankah.
- EDX (Data Register): Uporablja se za shranjevanje podatkov in rezultatov operacij.
- ESI (Source Index Register): Uporablja se za vir podatkov pri kopiranju ali manipulaciji podatkov.
- EDI (Destination Index Register): Uporablja se za ciljno lokacijo pri kopiranju ali manipulaciji podatkov.
- ESP (Stack Pointer Register): Označuje vrh pomnilnika (sklad), ki se uporablja za shranjevanje lokalnih spremenljivk in vrnitvenih naslovov funkcij.
- EBP (Base Pointer Register): Pogosto se uporablja za referenco na okvir funkcije.
- Ukazni register (Instruction Pointer Register):
- EIP (Instruction Pointer Register): Vsebuje naslov naslednjega ukaza, ki se bo izvedel. Uporablja se pri zaporednem izvajanju programov.
- Segmentni registri (Segment Registers):
- CS (Code Segment Register): Vsebuje naslov segmenta, ki vsebuje izvorno kodo programa.
- DS (Data Segment Register): Vsebuje naslov segmenta, ki vsebuje podatke.
- SS (Stack Segment Register): Vsebuje naslov segmenta, ki vsebuje sklad.
- ES (Extra Segment Register): Pogosto se uporablja za dodatne podatke.
- Posebni registri:
- EFLAGS (Flags Register): Vsebuje različne zastavice, ki označujejo rezultate prejšnjih operacij (npr. prenos, ničelnost, prekoračitev itd.).
- CR0 (Control Register 0): Uporablja se za nadzor osnovnih konfiguracijskih parametrov procesorja.
- CR2 (Control Register 2): Vsebuje naslov prekinitve strani v primeru napake v pomnilniku.
- CR3 (Control Register 3): Vsebuje naslov tabele strani (Page Table) za upravljanje virtualnega pomnilnika.
Ti registri so lahko različnih velikosti (npr. 8-bitni, 16-bitni, 32-bitni ali 64-bitni), odvisno od arhitekture procesorja. Uporaba in dostop do registrov je ključnega
Ukazi
| Ukaz | Opis |
|---|---|
| mov dest, src | Premakne podatke iz izvora (src) v cilj (dest). |
| add dest, src | Sešteje vrednosti iz cilja (dest) in vira (src). |
| sub dest, src | Odšteje vrednost vira (src) od cilja (dest). |
| mul src | Pomnoži vsebino ciljnega registra z vrednostjo vira. |
| div src | Deli vsebino dvojnega registra s vrednostjo vira. |
| jmp label | Nepogojni skok na oznako v programu. |
| je label | Skoči na oznako, če je nastavljena zastavica "enako". |
| jne label | Skoči na oznako, če ni nastavljena zastavica "enako". |
| int 0x80 | Sproži sistemski klic v operacijskem sistemu Linux. |
| push src | Potisne vrednost iz vira na sklad. |
| pop dest | Izvleče vrh vrednosti iz sklada in shrani v cilj. |
| cmp op1, op2 | Primerja dve vrednosti in nastavi ustrezne zastavice. |
Ta tabela vključuje samo nekaj primerov ukazov in njihovih opisov. Opomba, da so lahko ukazi in njihovi parametri odvisni od specifične arhitekture procesorja in operacijskega sistema, zato se lahko razlikujejo. Za podroben seznam ukazov in njihove uporabe se je vedno najbolje sklicevati na dokumentacijo specifične arhitekture ali referenčni priročnik za jezik assembly, ki ga uporabljate.
Primer v Assemblyju
section .data
hello db 'Hello, world!', 0
section .text
global _start
_start:
; Pisanje besedila na standardni izhod
mov eax, 4 ; Sistemski klic za pisanje
mov ebx, 1 ; Standardni izhod (stdout)
mov ecx, hello ; Naslov niza "Hello, world!"
mov edx, 13 ; Dolžina niza
int 0x80 ; Sproži sistemski klic
; Izstop iz programa
mov eax, 1 ; Sistemski klic za izhod
xor ebx, ebx ; Izhodna koda 0
int 0x80 ; Sproži sistemski klic
Ta program uporablja sistemski klic za pisanje (int 0x80) za izpis niza "Hello, world!" na standardni izhod. Niz je shranjen v odseku .data, in sicer v spremenljivki hello. Dolžina niza je 13, kar je nastavljeno v registru edx. Na koncu programa se uporabi sistemski klic za izhod, ki zaključi izvajanje programa in vrne izhodno kodo 0.