Lucifer of ZeroBit - Ja ljublju ASSEMBLY VIII. rész

ÚÄÄÄ ÚÄÄÄ ÚÄ ÚÄ ÚÄ ÚÄ ÚÄ ÚÄ ÚÄÚÄ ÚÄÚÄ ÚÄ ÚÄ ÚÄÄ ÚÄ ÚÄÄ ÚÄ ÚÄÄÄÄÄÄÄÄÄ ÚÄÄ ÚÄ Ú ÚÄ Ja ljublju ASSEMBLY ÚÄÄ ÚÄÄ ÚÄ ÚÄ ÚÄ ÚÄ VIII.rész ÚÄÄ ÚÄÄ ÚÄÄÄÄ ÚÄ ÚÄ Lássunk neki az osztásnak és társainak. A következő utasításoknál NEM lehet közvetlen értékeket használni. Csak regisztert, vagy memóriatartalmat.
MUL utasítás (unsigned MULtiplication):
Használat: MUL forrás Ha a forrás byte, akkor az AX=AL*forrás műveletet végzi el. Ha a forrás szó, akkor az AX*forrás műveletet végzi el. Ekkor az eredmény DX:AX-ben adja vissza, vagyis az eredmény nagyobb helyiértékű szavát DX-ben, az alacsonyabbat AX-ben adja meg. CF és OF akkor lesz 1, ha byte forrás estén AH-ban, szó forrás estén pedig DX-ben van legalább egy 1 értékű bit. Példa: MOV AL,56h ; AL-ben az egyik tényező, a másik 45h, ez most MOV CL,45h ; CL-ben van ,de lehet máshol is, 45h byte MUL CL ; ezért az eredmény AX-ben képződik és 172eh lesz MOV AX,3476h ; AX-ben az egyik tényező, a másik szó (1256h) MOV CX,1256h ; ezért eredmény DX:AX-ben lesz. A szorzás MUL CX ; eredménye 03c1eba4h. Ebből DX-be a felső szó ; vagyis 03c1h kerül, míg AX-be az alsó, 0eba4h
IMUL utasítás (Integer MULtiplication):
Használat: IMUL forrás Ez előjelesen szoroz. Ha a forrás byte, akkor AL-lel szorozza és az előjeles eredmény AX-ben lesz. Ha a forrás szó, akkor AX-szel szorozza és a szintén előjeles eredmény DX:AX-ben lesz a MUL-nál leírt felbontásban. CF és OF akkor lesz 1, ha byte forrás esetén AH az AL-nek, vagy szó forrás esetén DX az AX-nek előjeles bővítése.
DIV utasítás (unsigned DIVision):
Használat: DIV forrás Előjel nélküli osztás. Ha a forrás byte, akkor AX regisztert elosztja forrással. A hányados AL-be kerül, a maradék pedig AH-ba. Ha a forrás szó, akkor DX:AX regisztert (így együtt 32 bitesek) osztja el forrással. Ekkor a hányados AX-be, a maradék DX-be megy. A jelzőbiteket nem bántja. Példa: MOV AX,3465h ; az osztandó AX=3465h, az osztó CL=56h MOV CL,56h ; az eredmény AL=9bh, ez a hányados DIV CL ; és AH=53h, ez a maradék MOV DX,2345h ; Az osztandó felső szava DX-ben, alsó szava AX-ben MOV AX,8765h ; mivel duplaszót osztunk, az osztó CX-ben MOV CX,6543h ; az eredmény: a hányados AX=592bh és DIV CX ; a maradék DX=3a24h Az osztásnál vigyázni kell, mert ha 0-val osztunk, vagy a hányados nem fér el a neki kiszabott helyre, akkor osztáshiba, INT 00h hajtódik végre, ami gyakorlatilag a program végét jelenti, ugyanis a DOS ilyenkor visszaveszi a vezérlést és kilépteti a programot. Ez ellen vagy saját INT 00h megírásával (ehhez még nem tudtok eleget) vagy odafigyeléssel lehet védekezni. Ha elképzelhető, hogy az osztó helyén 0 van (pl.: memóriatartalommal osztasz), akkor osztás előtt ellenőrizd, hogy nem nulla-e. Ha pedig egy szót kis számmal osztasz, akkor inkább a dupla szavas osztást használd DX-ben 0-val, mert így biztos nem lesz a hányados túl nagy.
zzzzIDIV utasítás (Integer DIVision):
Használat: IDIV forrás Előjeles osztást végez. Egyébként ugyanaz, mint DIV. A maradék előjele megegyezik az osztandó előjelével. Következnek a bitforgató/léptető utasítások. A számláló minden utasításban egy közvetlen byte vagy a CL lehet. A cél mindenhol regiszter vagy memóriatartalom lehet.
SAL utasítás (Shift Arithmetic Left):
Használat: SAL cél, számláló A célt számlálószor balra lépteti, mégpedig úgy, hogy a jobb oldalon 0-t hoz be, a bal oldalon kilépő bitet pedig CF-be írja.
Példa: SAL AL,3 ; legyen AL=11010011b, ezt 3-szor léptetve ; AL=10011000b-t kapunk és CF=0 lesz, mert ; ez lépett ki utoljára a bal oldalon SAL AX,CL ; AX=1111011000111011b és CL=6, ekkor a léptetés után ; AX=1000111011000000b lesz és CF=1, mert az utolsó ; kilépő bit 1 volt
SAR utasítás (Shift Arithmetic Right):
Használat: SAR cél, számláló A célt számlálószor jobbra lépteti úgy, hogy a jobb oldalon kilépő bit CF-be kerül, a legfelső bit pedig ismétlődik. Ez az ismétlődő bit kerül SF-be is.
Példa: SAR AL,3 ; AL=10011010b legyen, ekkor AL=11110011b és CF=0 lesz
SHL utasítás (SHift logical Left):
Ugyanaz mint SAL.
SHR utasítás (SHift logical Right):
Használat: SHR cél, számláló A célt számlálószor jobbra lépteti, mint a SAR, de ez a bal oldalon 0-kat hoz be mindig.
Példa: SHR AL,2 ; legyen AL=11000011b, ekkor AL=00110000b és CF=1 lesz
ROL utasítás (ROtate Left):
Használat: ROL cél, számláló A célt számlálószor balra forgatja. A forgatás során a cél legmagasabb helyiértékű bitje a legalacsonyabba kerül, a többi bitet pedig eggyel balra lépteti a proci. A legmagasabb helyiértékű bit a CF-be is belekerül.
Példa: ROL AL,4 ; legyen AL=11001011b, az utasítás után AL=10111100h ; vagyis helyet cserélt az alsó és a felső 4 bit ; CF pedig 0, mert utoljára egy 0 lépett ki bal oldalon ROL BX,CL ; Legyen CL=6 és BX=110011111000011b, az utasítás után ; BX=111000011110011b és CF=1, mert ez lépett ki ; utoljára a bal oldalon
ROR utasítás (ROtate Right):
Használat: ROR cél, számláló A célt számlálószor jobbra forgatja úgy, hogy a cél legkisebb helyiértékű bitje a legmagasabba kerül, valamint belemásolódik CF-be is. A többi bit jobbra lép.
Példa: ROR AL,3 ; AL=11010001b, ekkor AL=00111010b és CF=0 lesz
RCL utasítás (Rotate through Carry Left):
Használat: RCL cél, számláló A célt számlálószor balra forgatja a CF felhasználásával. Úgy kell tekinteni, mintha CF lenne a cél legmagasabb helyiértékű bitje és ezután balra forgatnánk.
Példa: RCL AL,2 ; legyen AL=11100101b és CF=0, ekkor AL=10010101b és ; CF=1 lesz
RCR utasítás (Rotate through Carry Right):
Használat: RCR cél, számláló A célt számlálószor jobbra forgatja CF segítségével. Itt Łgy kell venni, hogy CF a cél legkisebb helyiértékű bitje és így forgatunk.
Példa: RCR AL,2 ; legyen AL=11100101b és CF=1, így AL=11111001b és ; CF=0 lesz Ezek az utasítások nagyon hasznosak lehetnek, mikor egy számot szorozni vagy osztani kell 2 hatványával. Hogy miért? Mert ha egy számot eggyel balra tolunk, akkor az olyan, mint ha 2-vel szoroztuk volna. Gondolj arra, hogy mi van akkor, ha egy decimális szám végére egy nullát írunk. A szám 10-szeresére nő. Egy bináris szám balra léptetése, ha a jobb oldalon egy 0-t hozunk be, pontosan ugyanazt jelenti mintha egy 0-t a végére írtunk volna, ezért a számrendszer alapjával szorzott értéke lesz. A számrendszer alapja most éppen 2. Jobbra forgatásnál éppen a fordítottja, vagyis 2-vel osztódik. DE!! Negatív számok osztásánál más a hányados képzése, mint IDIV esetén. A hányadost lefele kerekíti a léptetéses osztás, azaz a kapott hányados kisebb lesz, mint a valódi. Pozitív és negatív számokra is igaz, hogy ha többet léptetünk jobbra, akkor a maradékot nem jól kapjuk meg, mert a léptetés után CF mindig csak a legutolsó lépés maradékát (volt-e vagy sem) tárolja. Ezért az ilyen módŁ osztásokat ajánlott lépésenként elvégezni. Nézzünk egy példát erre a lefele kerekítésre! Léptessük -13-at jobbra háromszor, azaz osszuk el 8-cal. -13 kettes komplemensben ábrázolva 11110011b. Hajtsuk végre a SAR 11110011b,3 utasítást. Azért a SARt, mert ez megőrzi a szám eredeti előjelét I. léptetés: 11111001b CF=1 Az eredmény átírva decimálissá -7 és van egy maradék, mert CF=1. Már most látszik a lefele kerekítés (angolul ezt úgy mondják, hogy a "negative infinity", azaz a negatív végtelen felé kerekítenek, így talán érthetőbb, mi az a lefele kerekítés ebben az esetben), mert -13/2 az testvérek között is -6 és maradt -1, míg itt -7 és marad +1. II. léptetés: 11111100b CF=1 A hányados -4 és CF=1 maradékot jelez. Tehát -13/4 az -4 és marad +1. Ez így nem igazán jó, mert -4*4+1=-15. A baj az, hogy lazán elfelejtettük az előző maradékot. így az igazi maradék 11b azaz +3. Így már helyes az eredmény, de itt is eltér az IDIV-től, ami -3 hányadost és -1 maradékot adna vissza. III. léptetés: 11111110b CF=0 A hányados -2 és CF=0 nem jelez maradékot. Tehát -13/8=-2 és marad 0? Á, dehogy...! Megint nem figyeltük az előző maradékokat, ezért a tényleges maradék 011b=+3. Kész is vagyunk mert -2*8+3=-13!! Az IDIV bezzeg -1 hányadost és -5 maradékot adna vissza és ez is jó (sőt ez egyezik a suliban tanultakkal mert -13-ban a 8 egyszer van meg), mert -1*8-5=-13. Összegezve: -13/8 pontos értéke -1 és -2 között van. Lefele (negatív végtelen felé) kerekítve -2-t választom hányadosnak és ehhez kapom meg a maradékot, ami itt +3 lesz. Felfele (azaz 0 felé) kerekítve pedig a -1-et választom eredménynek és ehhez számolok maradékot. Remélem világos!? A következő cikkben elmondom a logikai műveleteket és végre visszatérünk a programhoz, ahonnan indultunk, de most már felfegyverkezve mindenféle hasznos tudással Lucifer of ZeroBit

©2000. Fearless Criminal Force. Minden jog fenntartva!