Ľudmila Jánošíková | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Programovanie v jazyku symbolických adries | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
pre 32-bitové procesory Intel | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Aritmetické inštrukcie
add register/pamäť, register/pamäť/číslo
(add)
Inštrukcia add sčíta obidva operandy a výsledok uloží do ľavého operandu. sub register/pamäť, register/pamäť/číslo (subtract)
Inštrukcia sub odčíta pravý operand od ľavého operandu a výsledok uloží do ľavého operandu. adc register/pamäť, register/pamäť/číslo (add with carry)
Inštrukcia adc sčíta obidva operandy a hodnotu príznakového bitu CF a výsledok uloží do ľavého operandu. Táto inštrukcia sa používa pri sčítaní celých čísiel dlhších než veľkosť univerzálneho registra v danom režime procesora. Vo virtuálnom režime sú univerzálne registre 32-bitové, preto nemôžeme v jednej operácii sčítať dve čísla väčšieho rozsahu. Ak je číslo uložené napr. v štyroch slovách (64 bitov), musíme operáciu sčítania vykonať v dvoch krokoch: najprv sčítať nižšie dvojslovo (32 bitov) operandov a potom sčítať vyššie dvojslovo aj s prípadným prenosom (ako keď na papieri sčítavate viacmiestne čísla od najnižšieho rádu). Príklad: Sčítajte premenné A a B typu qword a výsledok uložte do premennej C.
A DQ 0FFFFFFFFh
.386 Upozorňujeme, že medzi add a adc sa nesmie vyskytnúť inštrukcia, ktorá by zmenila hodnotu príznaku CF. Výsledok sčítania by nebol korektný. sbb register/pamäť, register/pamäť/číslo (subtract with borrow)
Inštrukcia sbb odčíta pravý operand a príznak CF od ľavého operandu a výsledok uloží do ľavého operandu. Používa sa pri odčítaní čísiel väčšieho rozsahu, ktoré sa nezmestia do univerzálnych registrov. inc register/pamäť (increment)
Inštrukcia inc zvýši hodnotu operandu
o 1. Môžeme to samozrejme urobiť aj pomocou inštrukcie add,
ale inc je rýchlejšia a stručnejšia (napr.
inc bx sa preloží do 1 bajtu, ale
add bx,1 do 3 bajtov). Všimnite si, že inštrukcia
inc (na rozdiel od add) nemení
príznak CF!
dec register/pamäť
(decrement)
Inštrukcia dec zníži hodnotu operandu o 1.
cmp register/pamäť, register/pamäť/číslo
(compare)
Inštrukcia cmp porovná operandy tak,
že pravý odčíta od ľavého, nastaví príznakové bity podľa výsledku operácie, ale
samotný výsledok nikam neuloží.
mul register/pamäť
(unsigned multiply)
Na rozdiel od operácií sčítania a odčítania, ktoré majú rovnaké inštrukcie pre operandy bez znamienka aj operandy so znamienkom, pri násobení a delení musíme rozlíšiť, s akými číslami pracujeme. Ak chceme násobiť čísla bez znamienka, použijeme inštrukciu mul, ktorá vynásobí operand obsahom akumulátora. Akumulátorom je register AL, AX alebo EAX podľa toho, aký je typ operandu. Podľa typu operandu sa tiež určí register, do ktorého sa uloží výsledok. Môžu nastať tieto prípady:
Príznakové bity OF a CF sa nastavia na 1, ak výsledok presiahne rozsah operandov, t.j. ak je väčší ako bajt, resp. slovo alebo dvojslovo. V opačnom prípade sa OF a CF vynulujú. Treba pamätať na to, že horná polovica výsledku sa zmení aj v prípade, keď výsledok nepresiahne rozsah operandov (registre AH, resp. DX alebo EDX sa vynulujú)! Z hľadiska rýchlosti je pri násobení 32-bitových registrov konštantami 2, 3, 4, 5, 8, 9 výhodnejšie používať namiesto inštrukcie mul inštrukciu lea, napr. lea eax,[eax+eax*2]; eax := 3*eax imul register/pamäť imul register, register/pamäť/číslo imul register, register/pamäť, číslo (signed multiply)
Inštrukcia imul vykonáva násobenie hodnôt so znamienkom. Ako vidíte, možnosti násobenia sa rozšírili o násobenie konštantou a o voľbu druhého operandu, v treťom prípade aj výsledku. Prvý tvar inštrukcie imul zodpovedá inštrukcii mul. V druhom prípade sa ľavý operand vynásobí pravým a výsledok sa uloží do ľavého operandu; obidva operandy musia mať rovnaký typ (word alebo dword), napr.: V treťom prípade sa navzájom vynásobia druhý a tretí operand zľava a výsledok sa uloží do prvého operandu zľava; opäť operandy musia mať rovnaký typ (word alebo dword). Príznakové bity OF a CF sa nastavia na 0, ak horná polovica výsledku je znamienkovým rozšírením dolnej polovice; v opačnom prípade sa nastavia na 1. div register/pamäť (unsigned divide)
Inštrukcia div vykonáva celočíselné delenie čísiel bez znamienka. Operand inštrukcie sa považuje za deliteľ. Delenec a registre, do ktorých sa ukladá podiel a zvyšok po delení, sú implicitné a závisia od typu operandu – pozri tab. 5. Príklad: mov ax,51 div dl ; al ¬ 5, ah ¬ 1 Ak delíme nulou, alebo ak sa podiel nezmestí do určeného registra, generuje sa prerušenie číslo 0.
idiv register/pamäť (signed divide)
Inštrukcia idiv vykonáva celočíselné delenie čísiel so znamienkom. Implicitné operandy inštrukcie sa určujú podľa tab. 5. Ako sme videli, pri delení musí byť delenec uložený v registroch, ktoré majú dvojnásobnú veľkosť než deliteľ. Ak má delenec rovnaký typ ako deliteľ, uložíme ho do dolného registra a horný register vynulujeme, napr. ak chceme obsah registra BH vydeliť obsahom registra BL, musíme vykonať nasledujúce príkazy: mov al,bh Takto to funguje pri delení čísiel bez znamienka. Pri delení so znamienkom musíme vykonať znamienkové rozšírenie dolnej polovice delenca do hornej polovice. Znamienkové rozšírenie majú na starosti 4 inštrukcie: cbw (convert byte to word)
Inštrukcia cbw konvertuje 8-bitovú hodnotu so znamienkom v registri AL na 16-bitovú hodnotu so znamienkom. Výsledok sa uloží do registra AX. Konverzia prebehne tak, že všetky bity registra AH sa naplnia najvyšším bitom registra AL. Napr. ak chceme číslo -15 ( = 0F1h) uložené v registri BH vydeliť číslom 2 v registra BL, vykonáme nasledujúce príkazy: mov al,bh cwd (convert word to doubleword)
Inštrukcia cwd konvertuje 16-bitovú hodnotu so
znamienkom v registri AX na 32-bitovú hodnotu so znamienkom. Výsledok sa
uloží do dvojice registrov DX:AX. Všetky bity registra DX sa naplnia najvyšším
bitom registra AX.
cwde
(convert word to doubleword extended)
Inštrukcia cwde konvertuje 16-bitovú hodnotu so
znamienkom v registri AX na 32-bitovú hodnotu so znamienkom v registri EAX.
cdq
(convert doubleword to quadword)
Inštrukcia cdq konvertuje 32-bitovú hodnotu so znamienkom v registri EAX na 64-bitovú hodnotu so znamienkom v dvojici registrov EDX:EAX. Ako poslednú zahrnieme do skupiny aritmetických inštrukcií inštrukciu neg register/pamäť (two's complement negation)
Inštrukcia neg zmení znamienko operandu (nahradí operand jeho dvojkovým doplnkom). Príznak CF sa nastaví na 0, ak má operandu nulovú hodnotu, inak sa nastaví na 1. Príklad: mov al,-15 ; al := -15 = 11110001b |
Načo je vám jazyk symbolických adries?
Architektúra moderných procesorov 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. |