Ľudmila Jánošíková | ||||||||||||||||||||||||||||
Programovanie v jazyku symbolických adries | ||||||||||||||||||||||||||||
pre 32-bitové procesory Intel | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
Spôsoby adresovania
Keď hovoríme o spôsoboch adresovania, máme na mysli rôzne spôsoby, ako sa v inštrukciách odvolávame na operandy v registroch alebo v pamäti. Implicitné adresovaniePri tomto spôsobe adresovania operand v zápise inštrukcie nevidíme. Ako príklad môžeme uviesť inštrukciu mul bl, ktorá vynásobí obsah registra AL obsahom registra BL a výsledok uloží do registra AX. V inštrukcii mul bl sú uvedené dve implicitné adresy: adresa 1. operandu (register AL) a adresa výsledku (register AX). Žiadna z týchto adries nie je explicitne zapísaná v inštrukcii. Sú dané typom inštrukcie a schopnosťami procesora. Všetky ďalej uvádzané typy adries sú adresy explicitné. Explicitné adresovaniePriamy operand (adresa 0. rádu) Hodnota operandu je zapísaná priamo v inštrukcii, nejde vlastne ani o adresu (preto adresa 0. rádu). Napr. v inštrukcii mov al,3 je číslo 3 priamym operandom. Priama adresa (adresa 1. rádu) Priama adresa sa používa najčastejšie. Je to v inštrukcii zapísané označenie registra alebo číslo pamäťového miesta, s ktorého obsahom inštrukcia pracuje. Príkladom môže byť inštrukcia add dx,[Alfa], ktorá sčíta obsah registra DX s obsahom premennej Alfa a výsledok uloží do DX. Obidva operandy inštrukcie sú priamou adresou. Meno premennej interpretuje prekladač ako offset v dátovom segmente. Hranaté zátvorky uzatvárajúce meno premennej nie sú povinné, majú len zdôrazniť, že pracujeme s hodnotou premennej, a nie s jej adresou. Nepriama adresa (adresa 2. rádu) Pri nepriamom adresovaní je v inštrukcii zapísaná adresa pamäťového miesta, na ktorom nájdeme adresu operandu (na tomto mieste nájdeme priamu adresu). Nepriame adresovanie v takejto podobe sa používa zriedka (napr. v inštrukciách nepriameho skoku). Za zvláštny prípad nepriameho adresovania
môžeme považovať nepriame adresovanie pomocou registra. V tomto prípade je
priama adresa uložená v niektorom registri procesora a inštrukcia obsahuje
adresu (meno) registra. Priamu adresu môžeme získať aj sčítaním obsahov dvoch
registrov, prípadne k nim môžeme ešte pripočítať konštantu - tzv. posunutie (displacement).
Priamu adresu môžeme vypočítať pomocou
V chránenom režime sa ktorýkoľvek 32-bitový univerzálny register môže použiť ako bázový register alebo (s výnimkou registra ESP) ako indexový register.
Segment operandu sa určuje podľa bázového registra:
Ako sme už uviedli, môžeme používať aj kombináciu bázových a indexových registrov,
napr. mov al,[ebx+edi]. Obsahy bázového a indexového registra sa
sčítajú a dostaneme offset, na ktorom budeme hľadať pravý operand. Segment sa
určí podľa použitého bázového registra, t.j. v tomto prípade by sa použil
dátový segment. V príkaze mov al,[ebp+esi+4] sa
odkazujeme do zásobníkového segmentu. Tento príklad zároveň ukazuje, že
k bázovému a indexovému registru môžeme pripočítať aj posunutie.
Nepriame registrové adresovanie sa
s výhodou používa pri spracovaní polí dát. Do bázového registra sa ukladá
adresa začiatku poľa (báza poľa alebo smerník na pole), zatiaľ čo indexový register slúži na
prechádzanie poľom. Ukážme si príklad na použitie bázových a indexových
registrov. Vypíšte na obrazovku znakový reťazec uložený
v premennej Retaz, ktorý je ukončený
nulou. Každý znak reťazca je v pamäti uložený
v jednom bajte v kóde ASCII. Reťazec je uložený zľava doprava, t.j.
prvý znak má najnižšiu adresu. Meno premennej interpretuje prekladač ako
adresu, na ktorej reťazec začína. Na obr. 7 je znázornené uloženie reťazca
„No nazdar!“. Kvôli lepšej čitateľnosti sú v pamäťových bunkách zapísané
znaky a nie ich ASCII kódy. Obr. 7. Uloženie reťazca v pamäti Z cvičných dôvodov
budeme reťazec vypisovať po jednotlivých znakoch. Nasledujúci program rieši
našu úlohu. Na výpis znaku použijeme procedúru WriteChar z knižnice Irvine32.lib.
mov edi,0; prvý znak má index 0
mov al,[edx+edi]; ulož do al znak na offsete edx+edi
cmp al,0; porovnaj al s nulou
je Koniec; ak sú rovnaké, choď na návestie Koniec
call WriteChar; vypíš znak, ktorého ASCII kód je v al
inc edi; zvýš index o 1 - prejdi na ďalší znak
jmp VypisZnak Bez nepriameho adresovania by sme cyklus na
výpis reťazca po znakoch ani nevedeli zostaviť. Pri výpise jedného reťazca by
sme vystačili s indexovým registrom. Príkaz na skopírovanie znaku
s indexom EDI do registra AL by potom bol
mov al,[Retaz+edi]. Ak by sme ale potrebovali
vypísať viacej reťazcov, mohli by sme časť programu medzi návestiami
Vypis a Koniec
zapísať ako procedúru. Pred jej
vyvolaním z hlavného programu by sme uložili adresu požadovaného reťazca
do registra EDX. Nepriame registrové adresovanie je podporované
aj pravidlami kódovania inštrukcií. Pokiaľ inštrukcia obsahuje len bázový
a/alebo indexový register (bez posunutia), potrebujeme na jej zakódovanie o 4 bajty
menej, ako keby sme v inštrukcii uviedli priamu adresu. Indexový register sa môže násobiť
číslom 2, 4 alebo 8, čo umožňuje zrýchliť prístup k položkám polí typu
word, dword,
resp. qword
(pozri kapitolu Premenné a návestia). Príklad: Rovnaký register môže dokonca byť
použitý dvakrát: ako bázový aj ako indexový register. Táto možnosť sa dá využiť
aj v 16-bitovom režime v niektorých inštrukciách, ktoré nepristupujú do
pamäti, napr. inštrukcia vynásobí obsah registra EAX piatimi.
Pretože ľubovoľný univerzálny register môže byť bázou aj indexom, otázka je, za čo ho bude
prekladač považovať a ktorý segment sa pri výpočte adresy použije.
Pravidlá sú nasledujúce: Ak sa v odkaze vyskytujú dva registre, len jeden
z nich sa môže násobiť, a ten sa potom považuje za indexový register;
druhý register bude bázový. Ak nie je použité násobenie, ľavý register bude
bázový, pravý indexový. Ak je použitý len jeden register, považuje sa za bázový
bez ohľadu na to, či ho násobíme konštantou alebo nie. |
Načo je vám jazyk symbolických adries?
Architektúra moderných procesorov Spôsoby adresovania Služby operačného systému MS-DOS Služby operačného systému Windows 95/98/NT/XP |
|||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||
Vydala Žilinská univerzita v Žiline, 2000. ISBN 80-7100-723-4. Otázky a pripomienky môžete poslať autorke. Naposledy upravené 28.9.2015. |