Smějeme se s assemblerem pro PowerPC
PowerPC není jen jeden procesor, je to celá rodina procesorů typu RISC. Jsou veselé a k nakousnutí, používají se často ve vestavěných systémech pro práci s obrazem a obecně multimédii a především byly v počítačích Apple, dokud je politika firmy nevyintelovala ze hry.
A protože psát v assembleru pro x86 nebo něco podobného (jako je i stará dobrá 8051) je pěkná nuda, bude fajn se trochu blíž podívat na nízkoúrovňové programování pořádného procesoru.
Pro začátek si můžeme vytvořit ukázkový příklad v C a zpětně ho rozložit, třeba program, který jen vrací pětku. Koneckonců, proč ne?
/* peklo.c */
int main() {
return 5;
}
Asi nemá smysl program jakkoliv komentovat. Provedeme jeho přeložení do jazyka symbolických adres, a to pomocí gcc.
gcc -S -O2 -fno-PIC -o peklo.s peklo.c
K čemu ty parametry? Podívejme se na to pořádně. Parametr -S říká, že výsledek bude převeden pouze do jazyka symbolických instrukcí, nikoliv rovnou do spustitelného kódu, -O2 provádí poněkud lepší optimalizaci a bez něj vzniká zbytečně komplikovaná patlanica. Nejdůležitější je ale -fno-PIC, které zajistí, že výsledek nebude v PIC (Position Independent Code), což by bylo pro začátek velice složité a zbytečně nepřehledné. A pro úplnost, -o je název výstupního souboru (v našem případě peklo.s).
Tak, teď se podíváme na výsledek a tiše užasneme :).
.machine ppc
.text
.align 2
.globl _main
_main:
li r3,5
blr
.subsections_via_symbols
Rozeberme si to podrobněji:
.machine ppc
je direktiva překladače, která mu říká, pro jakou architekturu je určen následující kód. V našem případě je to ppc, což je PowerPC. Dalšími možnostmi jsou např. ppc64, i386 nebo x86_64.
.text
(za předpokladu, že as voláme s parametrem -static) je zkratka pro zápis .section __TEXT,__text,regular. Tato direktiva překladači sděluje, že má nechat cokoliv následující za __TEXT, v sekci __text daného segmentu. Obsah sekcí může mít různé typy a typem v tomto příkladě je regular, kde se mohou nacházet jakákoliv data, a ta nebudou dále nijak zpracovávána.
.align 2
zarovná location counter na následující 4 bajty, pokud tedy už rovnou není. Zajišťuje, že bude tedy vždy dělitelný 22.
.glob _main
direktiva zajišťuje vytvoření reference na symbol _main jinými moduly.
_main:
je label pro symbol _main uložený v tabulce symbolů. GCC ho vytvořilo přidáním podtržítka před název funkce v C.
li r3,5
tohle je první skutečný zápis v jazyce symbolických adres, jedná se o pseudoinstrukci li (load immediate), která do registru r3 uloží onu osudnou pětku.
blr
druhá a poslední efektivní instrukce, branch unconditionally to LR, provede nepodmíněný skok na adresu v linkovém registru (LR).
.subsections_via_symbols
trochu nebezpečná direktiva umožňující překladači použít jakýkoliv symbol v libovolné sekci jako oddíl. To sice umožňuje použít nesčetné množství programovacích metod, ale z hlediska ručního psaní kódu to můžeme vesele ignorovat.
Tak to by byl kód. Teď z něj potřebujeme dostat objektový soubor. Ten samozřejmě získáme překladem pomocí as.
as -o peklo.o peklo.s
Čímž jsme tedy pod Mac OS X získali objektový soubor pro Mach - Mach-O file. To samozřejmě není všechno, aby to šlo spustit, musíme to (jako vše) slinkovat.
ld -lcrt1.o -lSystem -o peklo peklo.o
A tak je vytvořen spustitelný soubor, který je dynamicky nalinkován na knihovnu /usr/lib/libSystem.B.dylib, dynamicky linkovanou na /usr/lib/dyld. To zajistí veškerý kód kolem nutný pro spuštění. Podívat se na to můžeme pomocí otool.
A to by asi zas pro dnešek stačilo, tak příjemné hraní s PowerPC, papa!