Inštrukcie posuvov a rotácií |
||
| <= | => | |
Tieto inštrukcie sú dobrým pomocníkom každému, kto ich vie používať. Jedná sa o bitový posun vo vnútri slabiky, alebo slova. Počet bitov posuvu je špecifikovaný použitým registrom, alebo označením pamäťového miesta.
Posuvy:
Tvorba masky
Ak nevieme, ako
vytvoriť slabiku alebo slovo pre vymaskovanie, použijeme inštrukciu posuvu.
MOV AL, 1; SHL AL, 3. Takto získame slabiku s nastaveným
bitom na štvrtom mieste (00001000).
Celočíselné
delenie mocninou 2 a násobenie konštantou
Je to najdôležitejšie
použitie posuvov. Vychádza z faktu, že bitový posuv čísla doľava o jeden
krok je rovnaký, ako by sme číslo vynásobili dvomi. Naopak bitový posuv
čísla doprava o jeden krok je rovnaký, ako by sme číslo delili dvomi. Delenie:
Do registra umiestnime delenca. Ten potom posunieme doprava o toľko, koľkou
mocninou 2 je deliteľ:
#include <stdio.h>
unsigned int cislo;
main() {
scanf("%d",&cislo);
asm {
MOV AX,cislo // naber číslo do prvého registra
MOV BX, AX // naber číslo do druhého registra
SHL AX, 1 // v prvom registre raz doľava <=> vynásob 2
SHL BX, 4 // v druhom registre štyrikrát doľava <=> vynásob 16
ADD AX, BX // sčítaj obsahy oboch registrov
MOV cislo, AX // vráť cez premennú cislo
}
printf("cislo*18=%d",cislo);
}
Uvedený postup môžete jednoducho previesť na ľubovoľnú konštantu. Vzhľadom k zdĺhavosti násobenia inštrukciou MUL vám tento algoritmus občas zrýchli program.
Nasledujúci príklad vytvára reťazec informácií o čase. Ten si zistí z pamäti CMOS. Čítanie prevádzame tak, že na adresu portu 0x70 vyšleme číslo čítanej slabiky (0 - sekundy, 2 - minúty, 4 - hodiny) v CMOS. Z portu 0x71 potom prečítame jej hodnotu. Ta je v CMOS v zhustenom BCD tvare. Preto ju prevedieme na nezhustený a až potom na kód ASCII. Nakoniec dáta zapíšeme do premennej slovo v tvare, v akom je zvykom čas zapisovať. Program som optimalizoval tak, aby mal čo najmenší počet inštrukcií. Vzhľadom k tomu, že vo vloženom assembleri som nepoužil cyklus, tvorím ho pomocou “céčkového” for cyklu. Podobným spôsobom by sme čítali i iné užitočné informácie z pamäti CMOS (dátum, konfigurácie . . .).
#include <stdio.h>
#include <conio.h>
unsigned char i;
char slovo[254]=" . . ";
main() {
clrscr();
do {
for (i=0; i<= 2; i++) {
asm {
MOV BX,offset slovo // naber adresu premennej slovo
XOR AH,AH // vymaž hornú polovicu registra AX
MOV AL,i // naber do dolnej polovice AX krok i
SUB BX,AX // odčítaj od BX obsah AX
SHL AL,1 // vynásob, AL:=AL*2
SUB BX,AX // odčítaj od BX obsah AX
OUT 0x70,AL // pošli na CMOS adresu čítanej slabiky
IN AL,0x71 // prečítaj z CMOS obsah čítanej slabiky
MOV AH,AL // skopíruj obsah prečítanej slabiky do AH
SHR AH,4 // desiatky posuň do dolnej polovice AH
AND AX,0x0F0F // odstráň zbytočné bity
OR AX,0x3030 // urob prevod do ASCII
MOV 7[BX],AL // nastav jednotky v premennej slovo
MOV 6[BX],AH // nastav desiatky v premennej slovo
}
gotoxy (1,1);
printf("%s",slovo);
}
} while (!kbhit());
}
| <= | => |