Popis některých rysů programování procesorů Alpha v assembleru.
1. Kódování instrukcí
Při programování je nutné vzít v úvahu skutečnost, že Alpha je procesor RISC. Některé důsledky této skutečnosti lze shrnout do následujících bodů:
V registrové sadě je celkem 32 registrů pro celočíselné operace, označených $0 až $31. Registr $31 je "dummy register" - při čtení obsahuje 0, při zápisu se jeho obsah nemění. Ostatní registry jsou v podstatě rovnocenné, ale assembler a další překladače předpokládají jejich standardní využití. 12 registrů je určeno pro mezivýsledky a podobně, 6 dalších registrů je také určeno pro mezivýsledky - v procedurách jsou ukládány, 6 registrů slouží pro předávání argumentů do volané procedury, $26 obsahuje v proceduře návratovou adresu, $29 je "global pointer" pro adresování dat v paměti, $30 slouží jako stack pointer.
Při překladu nahrazuje překladač některé mnemonické kódy jinými instrukcemi se stejným výsledkem (tzv. pseudoinstrukce). Například instrukci
mov $1,$2
pro přesun dat z 1 do 2 nahradí strojovou instrukcí
bis $1,$1,$2 .
(Instrukce mov vůbec není v souboru strojových instrukcí).
Některé mnemonické instrukce instrukce jsou vlastně makra - při překladu se mahradí několika instrukcemi ve strojovém kódu. Příklad lze najít v souboru program_1.s . Po jeho překladu dostaneme binární soubor, který lze zavést do paměti a prohlížet pomocí debuggeru dbx. Provedeme-li dump paměti ve formátu instrukcí (viz manuálové stránky dbx), lze prozkoumat způsob překladu jednotlivých instrukcí.
Pozn.: dbx používá pro označení registrů symboly r0, r2, ..., r31. Některé registry mají navíc v různých situacích další "alias", např $30 je sp nebo také $sp apod.
Proměnná var1 je definována v sekci .sdata, do které je v průběhu výpočtu možný přístup pomocí "global pointer" registru $29 (alias gp alias $gp). Proto je instrukce
ldl $1,var1
přeložena jako
ldl $1,-32768(gp) .
Proměnná var2 je definována v sekci .data. Tato sekce svým umístěním v paměti nezaručuje možnost adresování pomocí gp. Proto je instrukce
ldl $2,var2
přeložena do dvou instrukcí strojového kódu:
ldah $2,-1(gp)
ldl $2,32656($2) .
První z nich uloží do $2 adresu proměnné var2 (resp. adresu sekce .data. Tato adresa je uložena v tzv. GOT - Global Offset Table, přístupné pomocí gp), druhá instrukce tuto adresu použije ke čtení var2 z paměti.
Podobně se překládají i instrukce sdl.
Dále je v programu vidět způsob překladu skokové instrukce. Původní instrukce
jmp lab1
je přeložena jako relativní (vzhledem k PC) skok (tzv. branch). Protože instrukce vždy ukládá návratovou adresu do určeného registru, je v tomto případě jako registr pro uložení návratové adresy použit "dummy" registr $31:
bsr $31,main+0x38(line 22) .
Adresa main+0x38 je adresa cíle v symbolickém tvaru. Ve strojovém kódu má tato instrukce kód 0xD3E00002. 00002 je hodnota, která se po vynásobení konstantou 4 přičítá k PC (tedy 00002 znamená zvětšení PC o 8, tj. přeskočení 2 následujících instrukcí).
Instrukce
bis $31, $31, $31 ,
která se ve strojovém kódu několikrát objevuje, je generována překladačem místo instrukce nop.
K dispozici je zdrojová forma programu program_1.s a kopie okna debuggeru dbx s dumpem paměti ve formátu symbolických instrukcí.
Dále je k dispozici popis procesorů Alpha. a manuál Assembly Language Programmer's Guide pro programování v assembleru.
2. Volání procedur
Při volání procedur se doporučuje zachovávat konvence používané při překladu programů z jazyka C. Tyto konvence jsou ovšem poměrně komplikované a překladačem podle konkrétní situace různě upravované za účelem zvýšení efektivity programu (různé stupně optimalizace). Doporučovaný postup při psaní procedury v assembleru je napsat nejprve tuto proceduru v C a přeložit ji (gcc s volbou -S) do assembleru. Takto získanou proceduru v assembleru lze potom podle potřeby upravovat při zachování jejího prologu a epilogu.
Několik základních pravidel pro prolog procedury lze shrnout do následujících bodů:
Postup při volání funkce lze sledovat např na programu program_2.c. Jeho překladem do assembleru je vytvořen soubor program_2.s, který demostruje výše uvedená pravidla. Podrobnosti lze najít v Assembly Language Programmer's Guide.
Poslední změna stránky byla provedena 12.12.2001