222 lines
No EOL
7.4 KiB
Markdown
222 lines
No EOL
7.4 KiB
Markdown
# Jazyk symbolických adres
|
||
|
||
**Proč programovat v JSA?**
|
||
- překladače vyšších jazyků nemusí umět využít speciální vlastnosti procesoru
|
||
- může být nutné napsat část kódu jinak, než jej generuje překladač
|
||
- možnost vytvořit optimalizovaný kód ???
|
||
+ cvičné důvody - programátor se musí důkladně seznámit s daným procesorem
|
||
|
||
**Program v JSA vs. strojový kód**
|
||
- program v JSA
|
||
- používá symbolické názvy instrukcí
|
||
- používá symbolické adresy operandů
|
||
- strojový kód = program přeložený do binární podoby
|
||
- obsahuje binární kódy instrukcí
|
||
- obsahuje absolutní adresy operandů
|
||
+ jediná forma programu, kterou umí procesor přímo zpracovat
|
||
+ velmi obtížné na úpravy a obtížně srozumitelné
|
||
|
||
**Symbolická adresa**
|
||
- nahrazuje ve zdrojovém kódu skutečnou (absolutní) adresu
|
||
- převod provede překladač + sestavovací program
|
||
- programátor nemusí znát skutečné umístění proměnné v paměti
|
||
- obsahuje
|
||
- **hodnotu** - adresu, kterou reprezentuje
|
||
- **obsah** - obsah paměťového místa (bytu, slova, ...) na které odkazuje
|
||
- použití
|
||
- **návěští** - cílová adresa skoku nebo volání procedury
|
||
- **proměnná** - adresa pro manipulaci s daty
|
||
- může být
|
||
- **absolutní** - hodnota je známá při překladu (může ji určit assembler)
|
||
- **relativní** - hodnotu určí linker (sestavovací program) při sestavování
|
||
|
||
**Překlad a sestavení programu**
|
||
- program je sestaven z jednoho nebo více modulů
|
||
- moduly se překládají samostatně
|
||
- přeložené (relativní) moduly se spojí sestavovacím programem do výsledného souboru
|
||
|
||
**Relativní a absolutní cesty**
|
||
- v realtivních modulech adresy počítány od začátku modulu
|
||
- v sestaveném programu adresy počítány od začátku paměti
|
||
|
||
**Zápis programu**
|
||
- program se zapisuje do 4 sloupců
|
||
- některá pole je možno vynechat
|
||
- každá řádka obsahuje jednu **instrukci**, **direktivu** nebo **rozvinutí makra**
|
||
- sloupce
|
||
- návěští - definuje symbolickou adresu
|
||
- operace - symbolický název instrukce nebo direktivy
|
||
- operandy - operandy instrukce nebo parametry direktivy
|
||
- komentář - nepovinný, oddělen středníkem
|
||
|
||
### Instrukční soubor
|
||
|
||
+ instrukce dělitelné do několika skupin
|
||
|
||
**Přesuny dat**
|
||
- operandy typu B, W, L
|
||
- B = byte (8 bitů)
|
||
- W = word (16 bitů)
|
||
- L = long (32 bitů)
|
||
- přesuny
|
||
- `paměť ↔ registr`
|
||
- `registr ↔ registr`
|
||
- `přímý operand → registr`
|
||
- lze použít různé adresní módy
|
||
- přesuny nastavují příznakové bity
|
||
|
||
**Aritmetické operace**
|
||
- operandy typu B, W, L.
|
||
- operace
|
||
- `registr * registr → registr`
|
||
- `přímý operand * registr → registr`
|
||
- sčítání, odčítání, inkrement, dekrement
|
||
- dekadická korekce
|
||
- násobení (8 × 8 → 16), (16 × 16 → 32), signed/unsigned
|
||
- dělení (16 : 8 → 8 + 8), (32 : 16 → 16 + 16)
|
||
|
||
**Porovnání**
|
||
- operandy typu B, W, L
|
||
- operace
|
||
- `registr * registr`
|
||
- `přímý operand * registr`
|
||
- formálně provede odečtení operandů (ale neuloží výsledek)
|
||
- použití obvykle s následnou instrukcí `BCC`
|
||
|
||
**Logické operace**
|
||
- operandy typu B, W, L.
|
||
- operace
|
||
- `registr * registr → registr`
|
||
- `přímý operand * registr → registr`
|
||
- logický součet (OR), součin (AND), nonekvivalence (XOR), negace (NOT)
|
||
|
||
**Bitové operace**
|
||
- nastavení, nulování, negace bitu.
|
||
- operace typu
|
||
- `Carry * bit → Carry`
|
||
- `Carry * bit → bit`
|
||
- operandy typu byte v registrech nebo v paměti
|
||
- bitové operace v paměti jsou typu Read – Modify – Write
|
||
|
||
**Posuvy a rotace**
|
||
- operandy typu B, W, L v registrech
|
||
- rotace s `Carry` nebo bez `Carry`
|
||
|
||
**Skoky** (JMP, JSR)
|
||
- přímá nebo nepřímá adresa
|
||
|
||
**Podmíněné skoky**
|
||
- relativní adresa 16 nebo 8 bitů
|
||
- signed, rozsahy <`PC`-32768, `PC`+32766> resp. <`PC`-128, `PC`+126>
|
||
|
||
**Řidící instrukce**
|
||
- uložení registrů CCR a EXR do paměti, resp. přečtení z paměti
|
||
- instrukce pro ladicí přerušení TRAPA
|
||
- návrat z přerušení RTE
|
||
- přechod do režimu sníženého odběru (SLEEP)
|
||
|
||
### Direktivy
|
||
|
||
- povely pro překladač
|
||
+ definice sekcí (segmentů)
|
||
+ definice dat a symbolů
|
||
+ makra
|
||
+ podmíněný překlad
|
||
+ ...
|
||
|
||
### Modul
|
||
|
||
**Struktura**
|
||
- modul obsahuje jednu nebo více sekcí (segmentů)
|
||
- každá sekce má nezávislé adresování od svého začátku
|
||
- pořadí sekcí ve zdrojovém souboru není podstatné - upraví se při sestavení
|
||
|
||
**Základní typy sekcí**
|
||
- datová
|
||
- obsahuje inicializovaná data programu
|
||
- kódová sekce
|
||
- obsahuje kód programu
|
||
- další sekce
|
||
- neinicializovaná data, zásobník, přerušovací vektory, ...
|
||
|
||
**Definice sekce**
|
||
- hlavička
|
||
- standardní sekce GNU as a ld
|
||
- `.data [subsekce]`
|
||
- `.text [subsekce]`
|
||
- libovolné další sekce
|
||
- `.section jméno`
|
||
|
||
**Počítadlo adres**
|
||
- každá sekce má (při překladu) samostatné počítadlo adres (PLC - Programm Location Counter)
|
||
- není-li určeno jinak, inicializuje se PLC na 0 na začátku sekce
|
||
- možnosti nastavení PLC
|
||
- `.org výraz` - nastaví PLC na hodnotu `výraz`
|
||
- `.align uložení` - nastaví PLC na hodnotu `MOD(2^uložení)`
|
||
- všechny adresy jsou vztaženy k začátku sekce
|
||
|
||
**Sestavení sekcí a modulů**
|
||
- sestavovací program spojí stejné sekce (popř. subsekce) dohromady
|
||
|
||
**Definice symbolů**
|
||
- definice a přiřazení hodnoty symbolu
|
||
- `.equ symbol, výraz`
|
||
- `symbol = výraz`
|
||
- nevyhrazuje místo v paměti
|
||
- platnost symbolu omezena na modul, kde je definován
|
||
- hodnotu nelze měnit
|
||
|
||
**Definice dat**
|
||
- definice místa pro proměnnou
|
||
- `[návěští] .space položky`
|
||
- `návěští` - symbolická adresa
|
||
- `položky` - počet položek
|
||
- vyhradí v paměti místo určené délky (počtu bytů)
|
||
+ definice proměnné s počáteční hodnotou
|
||
- `[návěští] .byte výrazy`
|
||
- `[návěští] .word výrazy`
|
||
- `[návěští] .long výrazy`
|
||
- `[návěští] .ascii řetězec`
|
||
- `[návěští] .asciz řetězec`
|
||
- `návěští` - symbolická adresa
|
||
- `výrazy` - obsah jednotlivých položek
|
||
- vyhradí v paměti místo, jehož obsah je dán jednotlivými výrazy
|
||
- je-li návěští uvedeno, odpovídá jeho hodnota adrese 1. bytu dat
|
||
|
||
**Sdílení dat mezi moduly**
|
||
- symboly platí pouze v modulu, kde jsou definované
|
||
- rozšíření platnosti (export)
|
||
- `.global symboly`
|
||
- použití symbolů z jiného modulu (import)
|
||
- `.extern symboly`
|
||
- `symboly` - exportované symboly oddělené čárkou
|
||
- lze použít pouze pro symboly definované jako návěští (ne `.equ`)
|
||
|
||
### Makra
|
||
|
||
- umožňují definovat část programu, která bude použita na více místech
|
||
|
||
```
|
||
.macro jméno argumenty
|
||
tělo makra, jednotlivé instrukce
|
||
.endm
|
||
```
|
||
|
||
- `argumenty` - seznam symbolických argumentů, v těle se referují s `\` na začátku
|
||
- rozvinutí makra vloží tělo makra do daného místa programu
|
||
|
||
**Lokální symboly**
|
||
- je-li v makru definován symbol, vznikají při vícenásobném rozvinutí problémy
|
||
- je potřeba jej definovat jako lokální - `LOCAL symboly` (oddělené čárkou)
|
||
- překladač vytvoří v každém rozvinutí unikátní jméno
|
||
- před použitím `LOCAL` je potřeba použít direktivu `.altmacro`
|
||
|
||
**Makra vs. procedury**
|
||
- použití makra
|
||
- kód makra je v paměti pro každé rozvinutí
|
||
- bez dodatečného zpoždění pro `JSR`, `RTS`, přenos parametrů, ...
|
||
- použití procedury
|
||
- výkonná část je v paměti pouze jednou
|
||
- dodatečné zpoždění pro `JSR`, `RTS`, ... (pomalejší než makro)
|
||
- makro obvykle rychlejší
|
||
- procedura obvykle úspornější |