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

ÚÄÄÄ ÚÄÄÄ ÚÄ ÚÄ ÚÄ ÚÄ ÚÄ ÚÄ ÚÄÚÄ ÚÄÚÄ ÚÄ ÚÄ ÚÄÄ ÚÄ ÚÄÄ ÚÄ ÚÄÄÄÄÄÄÄÄÄ ÚÄÄ ÚÄ Ú ÚÄ Ja ljublju ASSEMBLY ÚÄÄ ÚÄÄ ÚÄ ÚÄ ÚÄ ÚÄ VII.rész ÚÄÄ ÚÄÄ ÚÄÄÄÄ ÚÄ ÚÄ Mielőtt még elkezdenénk, van egy kis tartozásom. A múltkor az OF bitről nem a teljes igazságot írtam, ezért újra leírom a funkcióját. Az OF (Overflow Flag) segít az ELÕJELES számok értelmezésében. Mikor egy mûveletet elvégez a proci, csak a sima bináris aritmetikát figyeli, nem foglalkozik előjel bitekkel és egyebekkel. De itt az OF bit, aminek éppen ez a feladata. Mikor mondjuk összeadjuk a 8343h és a 8654h számokat, akkor a proci összeadja őket, az eredmény helyére 0997h kerül és a CF bit 1 lesz, jelezve az átvitelt. De mi van, ha én a két számot előjelesen képzeltem el. Ebben segít a proci OF-fel foglalkozó része. A számok előjeles értékei: a 8343h-é -31933, a 8654h-é -31148. Ezeket összeadva az eredmény decimálisan -63081. Ez hexában 10997h. Látható, hogy az első négy számjegy itt is 0997h, mint a sima összeadásban, ezért az eredmény ezen részét nem kell bántani. Az SF bit nem tudja jelezni, hogy negatív számról van szó, mert a 0997h legmagasabb bitje 0. De akkor honnan tudjam, hogy az eredményt negatívan is lehet értelmezni? Ezt jelzi az OF, vagyis a 0997-et értelmezhetem negatívként is. Ekkor a szám elé kell még képzelni egy 1-est (gyakorlatilag az OF-et) és így kell számolni az előjeles értékét. Nézzünk egy példát arra, hogy mikor lesz 0 az OF. Adjuk össze a 0d958h és a 303fh számokat. Az eredmény 10997h. A sima összeadás eredménye itt is ugyanaz, mint az előző esetben. Az eredmény (pl.:AX) helyére 0997h kerül és a CF 1 lesz. Most értelmezzük a számokat előjellel. A 0d958h előjelesen értelmezve a -9896 decimális számot adja, míg a 303fh a 12351-et. Ezeket összeadva a decimális eredmény 2455. Azaz 0997h. Ezen látszik, hogy nem értelmezhető negatívként, szemben az 10997h-val. Ebben az esetben OF 0 lesz. Röviden az OF azt jelzi, ha egy előjelesen is értelmezhető szám nem fér el egy byteon (az előjelével együtt). Egy szón a legkisebb ábrázolható előjeles szám a -32768, a legnagyobb pedig a +32767. Egy byteon a legkisebb -128 a legnagyobb +127. Ha az eredmény előjeles értelmezése ennél kisebb vagy nagyobb lenne, az OF 1 lesz. Ahhoz, hogy a helyes számot megkapjuk (például képernyőre való kiíráshoz) a következőket kell tenni: 1. Ha OF=0, akkor a számot kettes komplemensként felfogva írjuk ki. Tudjátok, mikor a 7. bit az előjel. Kiszámítását az előző számban olvashatjátok. 2. Ha OF=1, - ha SF is 1, az eredmény úgy jó, ahogy van, pontosabban a szám elé még egy 0-t elképzelve kell számítani a KETTES KOMPLEMENSÁT. - ha SF=0, akkor az eredmény elé egy egyest helyezve számold ki a kettes komplemensét Példa: az eredmény 0567h és SF=0, OF=1, akkor a helyes eredmény 10567h kettes komplemens értéke az eredmény 9234h és SF=OF=1, akkor az igazi eredmény 09234h kettes komplemensben Mindkét esetben használható értelemszerûen byte helyett szó. Persze ezzel csak akkor kell foglalkozni, ha előjeles számokkal dolgozol. (A kettes komplemens amúgy nem csak a számok értelmezését jelenti (úgy, ahogy az előző számban leírtam, hanem azt is, hogy két szám egymásnak kettes komplemense (kiegészítője), ha összegük nulla. Ehhez viszont kell a már leírt értelmezés.) Akkor mit is számít, hogy az előjeles vagy az előjel nélküli ugróutasítást használjuk. Nem kezdek elméleti fejtegetésekbe, mert azt lehet, hogy nem mindenki értené. Inkább 4 gyakorlati példán mutatom be a különbséget. Minden példa egy-egy számpárra fog épülni, amelyeket összehasonlítunk és megnézzük, hogy melyik ugrás mikor következik be. I. Először nézzük a 15h és a 34h számokat. Ezek bináris alakja: 15h=00010101b, 34h=00110100b. Amint látjátok mind a kettőt 8 bitre kiegészítve alakítottam át, mivel egy byte 8 bites. Most meg kell nézni, hogy a jelzőbitek hogy állítódnak be. A CMP 15h,34h mûvelet lesz a kiindulópont. Ilyen mûvelet persze nincs, helyette a mov al,15h, CMP al,34h mûveletpárt kell alkalmazni, de most a rövidség kedvéért marad a sima CMP. Ez a 15h-34h mûveletet hajtja végre. Mivel a kivonandó kisebb, mint a kisebbítendő, ezért egy kölcsönzésre lesz szükség. Mindjárt kiderül, mi ez, bár ezzel tizes számrendszerû kivonásnál is találkoztatok. 00010101b -00110100b 15h-34h=1e1h ----------- 111100001b Látható, hogy mikor a 0-1 mûveletet végezzük el (az 5. bitek kivonása), akkor a szomszédos helyiértékről kölcsönözni kell egy 1-est, hogy a 10b-1b mûveletet kapjuk, amit már el tudunk végezni. Ennek az eredménye 1b, amit le is írunk. Mehetünk tovább, de nem szabad elfelejteni a kölcsönt. A következő kivonás a 0b-0b lenne, de volt egy kölcsönzés, amit most visszaadunk, így lesz 0b-0b helyett 0b-1b. Ezt viszont megint csak kölcsönzéssel tudjuk elvégezni, de a kölcsönt megint visszaadjuk majd. Ez így megy addig, amíg van kivonandó helyiértékünk. Ha ezután is maradt még tartozásunk, akkor az leírjuk a mínusz jel alá, ahogy én is tettem. De egy byteban csak 0-7 bitek szerepelnek, a mínusz jel alatti számjegy pedig már a 8-ik bit (figyeljetek: a jobb szélső bit a 0-ik). Ezért ezt a plusz bitet a CF-be tesszük, ez jelzi, hogy a kivonás végén kölcsönzés volt, azaz a 15h kisebb, mint a 34h. A byte 7. bitje 1, ezért az SF jelzőbit 1 lesz. Mi lesz az OF-fel? A két számot előjelesnek feltételezve az eredmény -31 (0eah). Ez ábrázolható 1 byteon ezért OF=0 lesz. Végül mely ugróutasítások ugranak ez után (csak azokat nézem, amelyeknek van előjeles/nélküli párja). - JA és JAE nem ugrik mert CF=1. Vagyis a számokat előjel nélkül nézve 15h nem nagyobb, mint 34h. - JB és JBE elugrik, mert CF=1. A számokat előjel nélkül nézve 15h kisebb 34h-nál. - JG és JGE nem ugrik, mert SF<>OF. Előjelesen 15h nem nagyobb, mint 34h. - JL és JLE elugrik, mert SF<>OF. Előjelesen 15h kisebb 34h-nál. II. A következő számpár a 15h és a 87h legyen. Most már nem részletezem a kivonások menetét. Itt is a CMP 15h,87h az alap. A jelzőbitek állapota: 15h-87h=18eh. Az eredménybe 8eh kerül. CF=1 lesz, mert maradt egy kölcsönzés. SF is 1 lesz, mert 8eh 7. bitje 1. OF pedig 1 lesz, mert a számok előjeles értelmezése esetén az eredmény +142 (15h 21,87h -121 előjelesen, ezek különbsége 142). Ez a +142 előjelesen nem ábrázolható egy byteon, ezért lesz OF=1. Mik ugranak: - JA és JAE nem ugrik, mert CF=1. Előjel nélkül 15h nem nagyobb 87h-nál. - JB és JBE ugrik, mivel CF=1. 15h kisebb, mint 87h, előjel nélkl. - JG és JGE elugrik, mert SF=OF. Most figyelj: 15h előjelesen NAGYOBB 87h-nál (előjel nélkül kisebb, nézd meg JB-nél) - JL és JLE nem ugrik mert SF=OF. 15h előjelesen nem kisebb, mint 87h. Figyeld meg, hogy előjel nélkül kisebb. III. Most nézzük a 87h és 0b4h számokat. A jelzőbitek: 87h-0b4h=1d3h. Az eredményben 0d3h lesz. CF 1 lesz, mert volt kölcsön az utolsó helyiértéknél. SF is 1 mert 0d3h 7. bitje 1. OF viszont 0 lesz, mert előjelesen nézve a számokat (87h -121 és 0b4h -76) a -121-(-76)=-45 számot kapjuk, ami elfér egy byteon. A 0d3h-t előjelesen nézve éppen -45-öt kapunk. Az utasítások: - JA és JAE nem ugrik, mert CF=1. 87h nem nagyobb, mint 0b4h előjel nélkül. - JB és JBE ugrik, mert CF=1. Azaz előjel nélkül 87h kisebb 0b4h-nál - JG és JGE nem ugrik, mert SF<>OF. A 87h (-121) előjelesen nem nagyobb 0b4h-nál (-76). - JL és JLE ugrik, mivel SF<>OF. 87h előjelesen kisebb 0b4h-nál IV. Legyenek 0b4h és 87h a számok (az előző fordítottja) 0b4h-87h=2dh. Ez alapján a jelzőbitek: CF=0, mert nem maradt kölcsönzés az utolsó helyiértékre. SF=0, mert 2dh 7. bitje 0. OF is 0, mert előjelesen számolva -76-(-121)=45, ami elfér egy byteon. Tehát 0b4h előjelesen nagyobb 87h-nál (SF=OF, ezért JG ugrik) és előjel nélkül is nagyobb (CF=0, azaz JA fog ugrani). Van még két lehetőség a számok viszonyára, mikor az I. vagy a II. pontot fordítjuk meg úgy , ahogy a IV. pont a III. fordítottja. Ezeket vezesd le magad. Az elgondolásod helyességét például Turbo Debuggerrel ellenőrizheted le. Nekiláthatunk a matematikai mûveleteknek.
ADD utasítás (ADDition):
Használat: ADD cél, forrás Összeadja a cél és forrás értékeket és a eredményt a cél-ba teszi. A cél és a forrás lehet byte vagy szó, de meg kell egyeznie a típusuknak. A lehetséges cél és forrásokat az ASM.NG-ből lehet megnézni (tőlem megszerezhető). Jelzőbitek: CF - 1 lesz, ha az utolsó helyiértéken volt átvitel, vagyis ha az eredmény nem fér be a célba. pl.: 98h+0d4h=16ch, ez nem fér el 1 byteon OF - 1 lesz, ha az eredmény előjelesen értelmezve nem fér be a célba pl.: 87h+87h=10eh, a célba 0eh kerül, de a valódi érték nem 14, -242 (10eh kettes komplemense), ha előjelesen dolgozunk ZF - 1, ha az eredmény nulla SF - 1, ha az eredmény 7. bitje 1 AF - 1, ha a mvelet közben a legalsó négy bitről átvitel volt az 5. bitre PF - 1, ha az eredményben páros számú 1-es van Példa: MOV AX,1234h ; AX-be az egyik összeadandó ADD AX,4536h ; AX=AX+4536h
ADC utasítás (ADd with Carry):
Használat: ADC cél, forrás Csak annyiban különbözik az ADD-tól, hogy cél=cél + forrás + CF. Minden más egyezik. Ezt például duplaszavas összeadásnál használjuk, mikor az első összeadás esetleges átvitelét fel kell használni a másodiknál. Nem csak duplaszavas, hanem akárhány szavas összeadásra is alkalmas, csak tovább kell vinni. Példa: MOV AX,1234h ; Ez most a 34561234h számhoz (BX:AX) adja ADD AX,0F564h ; hozzá a 5436f564h számot. Két lépés kell: MOV BX,3456h ; először összeadni az 1234h és a 0f564h ADC BX,5436h ; számokat, majd az átvitel figyelembevé- ; telével összeadni a 3456h és az 5436h ; számokat
SUB utasítás (SUBtraction):
Használat: SUB cél, forrás A cél=cél - forrás mveletet hajtja végre. A cél és a forrás lehet byte vagy szó. A forrás lehet byte hosszúságú is, ha a cél egy szó. Ekkor a byteot 16 bitesre kiterjeszti kivonás előtt. A jelzőbitek ugyanakkor állítódnak be, mint összeadáskor.
SBB utasítás (SuBtract with Borrow):
Használat: SBB cél, forrás A különbség a SUB-hoz képest annyi, hogy ez a cél=cél - forrás - CF mûveletet végzi el. Több szóból álló kivonásnál hasznos, mert az előző kivonások esetleges kölcsönzéseit (borrow) figyelembe veszi. Példa: MOV AX,1234h ; A 64561234h-76873456h mveletet kell SUB AX,3456h ; elvégezni. Először 1234h-ból ki kell MOV BX,6456h ; vonni 3456h-t, majd az esetleges SBB BX,7687h ; átvitelt figyelembe véve 6456h-ból le ; kell vonni 7687h-t A szorzás, osztás és a többiek a következő cikkben. Lucifer of ZeroBit

Š2000. Fearless Criminal Force. Minden jog fenntartva!