Eida.cz - Smějeme se s assemblerem pro PowerPC

Smějeme se s assemblerem pro PowerPC

10. července 2009, 15:24 Eida

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!

Eida
Tento článek přečetlo již 278 čtenářů (0 dnes).

Komentáře

Nový komentář