進制算術運算_第1頁
進制算術運算_第2頁
進制算術運算_第3頁
進制算術運算_第4頁
進制算術運算_第5頁
已閱讀5頁,還剩87頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

進制算術運算10.1加法與減法指令(ADD與SUB)ADD與SUB指令是加法與減法指令,可進行二進制數的字節(jié)或字的加、減運算。加法運算與手工加法相似,按逢二進一求和。而對于減法運算,計算機是利用對減數求補與被減數相加的方法來處理。方法是:將第二個操作數(減數),每一位變反(0→1或1→0),然后加1,這個過程稱為求補;最后再與第一個操作數(被減數)相加。對于操作數的尋址有下列五種可能:立即數與存儲器的加/減立即數與寄存器的加/減寄存器與寄存器的加/減寄存器與存儲器的加/減存儲器與寄存器的加/減

例10.1

加法指令ADD與減法指令SUB的使用。其中,子程序B10ADD使用ADD指令來處理字節(jié)的相加,C10SUB使用SUB指令來處理字的相減。源程序清單如下:

; ;—————————————————————CODESEGMENTASSUMECS:CODE,DS:CODE,SS:CODEORG100HBEGIN:JMPSHORTMAIN;—————————————————————BYTEADB64H ;數據定義BYTEBDB40HBYTECDB16HWORDADW4000HWORDBDW2000HWORDCDW1000H;—————————————————————MAINPROCNEARCALLB10ADD ;調用加法子程序

CALLC10SUB ;調用減法子程序RETMAINENDP;—————————————————————B10ADDPROCMOVAL,BYTEAMOVBL,BYTEBADDAL,BL ;寄存器與寄存器

ADDAL,BYTEC ;存儲器與寄存器

ADDBYTEA,BL ;寄存器與存儲器ADDBL,10H ;立即數與寄存器

ADDBYTEA,25H;立即數與存儲器

RETB10ADDENDP;—————————————————————C10SUBPROCMOVAX,WORDAMOVBX,WORDBSUBAX,BX ;寄存器與寄存器SUBAX,WORDC ;存儲器與寄存器

SUBWORDA,BX;寄存器與存儲器

SUBBX,1000H ;立即數與寄存器

SUBWORDA,256H;立即數與存儲器

RETC10SUBENDP;—————————————————————CODEENDSENDBEGIN

因為不允許存儲器與存儲器之間直接進行數據運算,所以可以使用寄存器來作為中間橋梁。例如,WORDA與WORDB均定義成WORD(字),要將WORDA加到WORDB的運算,可以寫出如下語句:

MOVAX,WORDAADDAX,WORDBMOVWORDB,AX

1.溢出一個字節(jié)所能表示的帶符號二進制數的范圍為-128~+127,當運算的結果超出這個范圍時就稱為溢出。通常的算術運算很容易超過一個字節(jié)寄存器的容量。例如,當寄存器AL中的和超過其最大容量時,不會自動地將溢出擴充到AH寄存器中。假設AL=60H,若

ADDAL,20HAL中將產生和的結果80H;同時設定溢出標志位CF=1,符號標志位SF=1。80H的二進制為,表示為一個負數為-128。兩個正數求和結果為負,這是為什么?問題的原因就是AL寄存器的容量太小,需要將和放在AX寄存器中。下列CBW指令可將字節(jié)轉換成字,將AL中的60H根據其正負號擴展AH成為0060H存入AX中。這時ADD在AX中才能產生正確的結果:0080H或+128。

CBW ;將AL擴展到AHADDAX,20H ;20H加入AX中2.多字節(jié)加法例10.2

多字節(jié)加法。源程序清單如下:;多字節(jié)加法

CODESEGMENTPARA‘CODE’ASSUMECS:CODE,DS:CODE,SS:CODEORG100HBEGIN:JMPSHORTMAIN;—————————————————————WORD1ADW0123H ;數據定義

WORD1BDW0BC62HWORD2ADW0012HWORD2BDW553AHWORD3ADW?WORD3BDW?;—————————————————————MAINPROCNEARCALLD10DWD;調用加法子程序1CALLE10DWD;調用加法子程序2RETMAINENDP;———————加法子程序1D10DWDPROCMOVAX,WORD1BADDAX,WORD2BMOVWORD3B,AXMOVAX,WORD1AADCAX,WORD2AMOVWORD3A,AXRETD10DWDENDP;———————加法子程序2E10DWDPROCCLCMOVCX,02LEASI,WORD1BLEADI,WORD2BLEABX,WORD3BE20:MOVAX,[SI]ADCAX,[DI]MOV[BX],AXDECSI ;寄存器與寄存器

DECSI ;存儲器與寄存器

DECDIDECDIDECBXDECBXLOOPE20 ;寄存器與存儲器

RETE10DWDENDPCODEENDSENDBEGIN

例10.2進行的是0123BC62+0012553A。例10.2中,加法子程序1?(D10DWD)將一對字(WORD1A與WORD1B)加到第二對字(WORD2A與WORD2B),將和存到第三對字(WORD3A與WORD3B)中。運算先加最低的字:WORD1BBC62WORD2B553A

和1119C

和為十六進制1119C,超過了AX寄存器的無符號數最大容量,進位標志CF=1。下面將高字相加,ADC指令連同進位CF一起求和。WORD1A0123WORD2A0012CF?1

和0136

使用DEBUG追蹤該算術運算,將會觀察到AX中存有0136,WORD3A存有3601,WORD3B存有9C11。例10.2中,加法子程序2(E10DWD)可以作任意長度的加法。從數據的最低位開始加起,第一次循環(huán)加最低的字,第二次循環(huán)加次低的字,所以,SI、DI、BX的內容需要減2??梢杂脙蓷lDEC減1指令,實現遞減的運算。請注意,指令

SUB寄存器,02

將會影響標志位,清除進位標志CF,產生不正確的結果。

因為使用循環(huán),所以僅使用一次加法指令ADC。開始的CLC指令將進位標志CF清為0。使用循環(huán)的方法有如下要求:①字的定義必須是連續(xù)的;②由低地址到高地址處理;③CX的初值為相加的字數。多字的減法是用帶借位的減法指令SBB取代ADC,就是將子程序2(E10DWD)中的ADC以SBB取代。10.2無符號數與帶符號數

某些數是無符號的,例如用戶編號和日期。某些數是帶符號的數,例如用戶應付的金額,溫度的讀數可能包含正值或負值。又例如產品價格和付款值永遠都被認定為正值。表10-1給出了與寄存器寬度相匹配的無符號和帶符號數據的最大值。表10-1無符號數與帶符號數的最大值格式字節(jié)(8位)字(16位)無符號25565535帶符號+127+32767

對于不帶符號的數,所有的位都表示數。8位寄存器可容納的最大值是255(28-1),16位寄存器可容納的最大值是65535(216-1)。帶正負號的數最高位表示正負號。在計算機中加、減法指令對于是否有正負號并不加以區(qū)別,而是所有的位都作加、減運算。下列為兩個二進制數相加,第一個數最高位為1,對于不帶符號的數,代表249,如果是帶符號數,則表示為-7:

無符號數帶符號數

11111001249-700000010

2

+211111011251?-5

帶正負號與不帶正負符號的運算結果是相同的。然而不帶符號的結果是251,帶符號的結果是-5。但是,其中總有一個應是你所需要的。當不帶符號數的和產生進位(CF=1)時,其結果不正確。

無符號數帶符號數CFOF11111100??252?-4

00000101

5

+5000000011+110

不正確

當有符號數的和有進位給符號位卻沒有產生最高位進位,或沒有進位給符號位卻有最高位的進位時,其結果不正確即有溢出。無符號數帶符號數CFOF01111001121+121

00001011

11

+1110000100132-12401

不正確進位和溢出同時發(fā)生的情況如下:無符號數帶符號數CFOF11110110?246?-10

10001001

137

-11901111111127+12711

不正確不正確10.3乘法

對于乘法,MUL指令用于處理無符號數乘法,IMUL用來處理帶符號數乘法。作為一個程序設計員,你必須控制所處理的數據格式并選擇適當的指令。兩個基本的乘法運算如下:1.字節(jié)乘字節(jié)被乘數放在AL寄存器中,乘數放在寄存器或存儲器的一個字節(jié)單元中(OPR),將乘積放在AX寄存器中。此運算會清除原存放在AH中的數據。如圖10-1中的OPR是指令中的操作數,若OPR是字節(jié)型數據,AL的值與OPR相乘,16位的乘積放到AX中。圖10-1字節(jié)乘法2.字乘字被乘數放在AX寄存器中,乘數放在寄存器或存儲器的一個字單元中,將結果乘積的高16位部分放在DX中,低16位部分放在AX中。此運算將會清除原存于DX中的數據。若OPR是字型數據,把AX的值與OPR相乘,32位的乘積放到DX與AX中;DX放乘積的高16位,AX放乘積的低16位,如圖10-2所示。圖10-2字乘法MUL與IMUL指令中僅指定一個操作數(乘數)。指令如下:

MULMULTR;MULTR是存儲器單元指令默認被乘數一定放在AL或AX中,乘積的存放位置也是由指令本身確定的。這種由指令本身限定必須使用的操作數,稱為隱含操作數。乘法中的乘數則需要在指令中用操作數的形式指明。如果MULTR定義為DB,則假設AL乘以字節(jié)數據;如果MULTR定義為DW,則假設AX乘以字數據。

當乘數放在寄存器中時,寄存器的長度決定運算數據的類型,如下所示:

MULCL

;1字節(jié)數據相乘:被乘數放在AL,乘積放在AXMULBX

;1字數據相乘:被乘數放在AX,乘積放在DX:AX10.3.1無符號數乘法指令MULMUL指令用作無符號數的相乘。例10.3中C10MUL給出三個乘法的例子:字節(jié)乘以字節(jié),字乘以字和字乘以字節(jié)。第一個例子為十六進制80(128)與十六進制40(64)兩數相乘,乘積十六進制2000(8192)放在AX中。第二個例子所產生的乘積為十六進制,存放在DX:AX中。例10.3

乘法指令范例。源程序清單如下:

;乘法范例TITLEEXMULT(COM)ExampleMUL&IMULoperationsCODESGSEGMENTPARA‘CODE’ASSUMECS:CODESG,DS:CODESG,SS:CODESGORG100HBEGIN:JMPSHORTMAIN;—————————————————————BYTE1DB80HBYTE2DB40HWORD1DW8000HWORD2DW2000H;—————————————————————MAINPROCNEARCALLC10MULCALLD10IMULRETMAINENDP;———————ExamplesofMULC10MULPROCMOVAL,BYTE1MULBYTE2

MOVAX,WORD1MULWORD2MOVAL,BYTE1SUBAH,AHMULWORD1RETC10MULENDP;———————ExamplesofIMULD10IMULPROCMOVAL,BYTE1IMULBYTE2

MOVAX,WORD1IMULWORD2

MOVAL,BYTE1CBWIMULWORD1RETD10IMULENDPCODESGENDSENDBEGIN

第三個例子是字與字節(jié)數據的乘,必須將BYTE1擴展為一個字數據。因為數值假設為無符號數,所以AH寄存器最高位假定為0,若使用CBW指令最高位可能是0或1。乘積存于DX:AX中,為十六進制。10.3.2帶符號數乘法指令IMULIMUL指令用來處理帶符號數相乘。例10.3中D10IMUL使用類似C10MUL中的三個范例,將MUL以IMUL取代。第一個例子中將十六進制80(負數)乘以十六進制40(正數)。乘積為十六進制E000,存入AX寄存器中。使用相同的數據,MUL則產生十六進制2000的結果。由此可以看出使用MUL與IMUL兩者的差別。MUL將十六進制80看作+128,IMUL則認為80為-128。-128與64二者相乘的乘積為-8192,相當于十六進制的E000H。

第二個例子將十六進制8000(負數)乘以十六進制2000(正數)。乘積為十六進制F0000000,存于DX:AX中,它是IMUL所產生的負值乘積。第三個例子將AX中的BYTE1擴展為一個字數據。因為數值被假定為帶符號數,所以此處必須使用CBW將最高位擴展到AH寄存器:在AL中的十六進制80,使AX中的十六進制數為FF80。

因為乘數WORD1也是負數,所以乘積為正。實際上在DX:AX中的十六進制與MUL有相同的結果。MUL是假定兩個正數相乘。實際上,如果乘數與被乘數有相同的正負符號,則MUL與IMUL會產生相同的結果。但如果乘數與被乘數的正負符號不相同,則MUL產生一個正號的乘積,IMUL則產生一個負號的乘積。你可以用DEBUG來追蹤上述的例子。10.3.3運算效率如果乘數是2的乘方如2、4、8等,使用向左移位將更有效率,左移1位相當于乘2,左移2位相當于乘4,左移3位相當于乘8。超過一次的移位,需將移位的次數存入CL寄存器中。下例中假設被乘數存放在AL或AX中:

SHLAL,1 ;AL左移1位乘2MOVCL,3SHLAX,CL ;AX左移3位乘810.3.4多字節(jié)數的乘法字所能容納的最大的帶符號數為+32767。若要處理更大的數值,則需要用特殊處理的方法。處理的算法是將多字分別相乘并將各乘積相加。例如,下面十進制的乘法:1365×122730136516380

如果十進制算術僅能處理兩位數的相乘,將如何處理?你可以將13與65分別乘上12,如下例所示:1365×12×1226130?1365156780

然后將兩乘積相加,但應記得,因為13是百位數,所以實際上的積應該為15600,結果為15600+7801638010.4除法

對于除法,DIV指令用來處理無符號數除法,IDIV指令用來處理帶符號數除法。你可以根據實際的需求來加以選擇?,F將指令的功能介紹如下。1.字除以字節(jié)被除數放在AX中,除數為一字節(jié)數據,存放在寄存器或存儲器單元中。運算完畢后,余數放在AH中,商放在AL中,見圖10-3。因為一個字節(jié)的商非常小,無符號數的最大值為+255(十六進制FF),帶符號數的最大值為+127(十六進制7F),所以指令的運算可用性不高。

圖10-3字節(jié)除法圖10-4字除法2.雙字除以字被除數放在DX:AX中,除數為一字數據,存放在寄存器或存儲器單元中。運算完畢后,余數放在DX中,商放在AX中,見圖10-4。一個字的商,無符號數時最大值為65535(十六進制為FFFF),帶符號數時的最大值為+32767(十六進制為7FFF)。與乘法指令類似,DIV指令也限定了隱含的操作數,包括被除數和結果的存放位置。特別的是,除法運算的結果包括商和余數兩部分。DIV與IDIV的操作數是指除數而言,假設指令如下:

DIVDIVISOR;DIVISOR是存儲單元如果DIVISOR定義成DB,則運算被看作是字節(jié)除法;如果DIVISOR定義成DW,則運算被看作是字除法。10.4.1無符號數除法指令DIV

例10.4中子程序D10DIV提供4個例子:字除以字節(jié),字節(jié)除以字節(jié),雙字除以字,字除以字。第一個例子是以十六進制的2000(8192)除以十六進制的80(128),余數00存放在AH中,而商為十六進制40(64),存放在AL中。第二個例子中先將BYTE1擴展為字數據。因為假定為無符號數,故AH所有的位設定為0。余數十六進制12存放在AH中,商為十六進制05,存放在AL中。

第三個例子產生的余數為十六進制1000,存放在DX中,商為十六進制0080,存放在AX中。第四個例子中需將WORD1擴展為雙字,存于DX中。運算完畢后得出余數為十六進制0000,存放在DX中,商為十六進制0002,存放在AX中。例10.4

除法指令范例。源程序清單如下:

;除法指令范例

TITLEEXDIV(COM)ExamplesofDIV&IDIVoperationsCODESGSEGMENTPARA‘CODE’ASSUMECS:CODESG,DS:CODESG,SS:CODESGORG100HBEGIN:JMPSHORTMAIN;—————————————————————BYTE1DB80HBYTE3DB16HWORD1DW2000HWORD2DW0010HWORD3DW1000H;—————————————————————MAINPROCNEARCALLD10DIVCALLE10IDIVRETMAINENDP;—————————————————————;————————ExamplesofDIVD10DIVPROCMOVAX,WORD1DIVBYTE1MOVAL,BYTE1SUBAH,AHDIVBYTE3MOVDX,WORD2MOVAX,WORD3DIVWORD1MOVAX,WORD1SUBDX,DXDIVWORD3RETD10DIVENDP;———————ExamplesofIDIVE10IDIVPROCMOVAX,WORD1IDIVBYTE1MOVAL,BYTE1CBWIDIVBYTE3MOVDX,WORD2MOVAX,WORD3IDIVWORD1MOVAX,WORD1CWDIDIVWORD3RETE10IDIVENDPCODESGENDSENDBEGIN10.4.2帶符號數除法指令IDIVIDIVOPR是帶符號數的除法指令。例10.4中子程序E10IDIV提供了類似D10DIV中的四個例子,僅用IDIV取代了DIV。第一個例子以十六進制2000(正數)除以十六進制80(負數)。余數為十六進制00,存于AH中,商為C0(-64),存于AL中。使用相同的數據,以DIV指令處理時,其商為+64。其余的三個例子所得的結果如下:IDIV余數商(2)EE(-18) FB(-5)(3)1000(4096) 0080(128)(4)0000 0002

只有第四個例子會產生與DIV相同的結果。事實上,如果被除數與除數為同符號時,則DIV與IDIV有相同的結果。但如果二者正負號不同時,則DIV的商為正,IDIV的商則為負。你可以用DEBUG來追蹤以上的例子。帶符號數的除法還涉及到余數的符號問題。例如,(+5)除以(-3)可以有兩種計算結果:一種是商為-1,余數+2;另一種是商為-2,余數-1。盡管這兩種結果都有其正確的含義,但在計算機中卻不能允許兩種結果并存。8086/8088及高檔次的Intel系列CPU在設計上對這一問題做了規(guī)定:余數與被除數的符號相同,因此前一種結果是正確的。10.4.3運算效率如果除數為2的乘方(2、4、8等),則用向右移位的方法將更有效。以下的例子,假定被除數存于AX寄存器中:

SHR AX,1 ;AX右移1位除以2MOV CL,3SHR AX,CL ;AX右移3位除以810.4.4溢出與中斷使用DIV特別是IDIV指令,存放除數、商和余數的位數相等;而被除數的位數是它們的兩倍,商就有可能不夠放。這種商不夠放的現象稱為“除法溢出”,當除數為0時也視為“溢出”;“溢出”所引起的中斷是不可預料的,將在屏幕上顯示溢出信息“DivideOverflow”,并結束該指令所在程序的執(zhí)行,返回操作系統。

除法產生溢出的規(guī)則之一:若除數是一個字節(jié),它的內容必須小于被除數的最左邊的字節(jié)(AH);若除數是一個字,它的內容必須小于被除數最左邊的字(DX),否則就會產生“溢出”。例如,除數為1時,所產生的商與被除數相同,就會引起中斷的發(fā)生,其他值也適用。例如:被除數除數商

012301 [1]2300014926 0001 [1]4026

上述兩個例子,商都超過存放它的寄存器的最大容量。編程時你可以在DIV或IDIV運算之前加以檢測,做出選擇。例如,下面的第一個例子,假設DIVBYTE是一個字節(jié)的除數,被除數存于AX中。第二個例子中DIVWORD是一個字的除數,被除數存于DX:AX中。

字除以字節(jié)雙字除以字

CMPAH,DIVBYTE CMP AX,DIVWORDJNBOVERFLOW-RTNE JNB OVERFLOW-RTNEDIVDIVBYTE DIV DIVWORD

對于IDIV,必須考慮到除數與被除數可能為負值的情況。方法是檢測除數的符號,可以暫時使用NEG指令將負數設為正數。

10.5改變符號和符號擴展指令10.5.1改變符號指令NEGNEG指令用于改變二進制數的正負號,即從正號變?yōu)樨撎柣驈呢撎栕優(yōu)檎枴EG指令類似于NOT指令,先將所有的位由0變1、由1變0,然后再加上1。假設,AX為十六進制FFFF(-1),BL為十六進制FF(-1),BINAMT為十六進制0001(+1)。例如:NEGAX ;AX=0001NEGBL ;BL=01NEGBINAMT(在內存的字或字節(jié))

;[BINAMT]=FFFF結果

要改變32位或更大數值的正負號,需要更多的步驟;假設在DX:AX中含有32位的二進制數,由于NEG指令不能對DX:AX同時起作用,若使用NEG指令將引起不正確的結果。而應使用NOT指令:

NOTDX ;取DX的反碼

NOTAX ;取AX的反碼

ADDAX,1 ;AX加1ADCDX,0 ;進位加給DX

10.5.2字節(jié)轉換成字指令CBWCBW指令對AL中的帶符號數進行符號擴展;當AL<0時,AH被賦值為0FFH,否則AH被置為0。該指令不影響所有標志位。

CBW指令用來將一個8位的帶符號數變換成與其等值的16位帶符號數,要求原數據放在AL中,而轉換結果放在AX中,并且AX中的低8位部分(AL)不變。CBW指令一般與IDIV指令配合使用。當程序中需要用一個字節(jié)型帶符號數去除以另一個字節(jié)型帶符號數時,按IDIV指令的要求,必須把字型的被除數放在AX中。為此,就需要用CBW指令,把存放在AL中的字節(jié)型被除數進行符號擴展變成字型帶符號數。然后,才能用IDIV指令進行除法運算。10.5.3字轉換成雙字指令CWDCWD指令將AX中的符號擴展到DX中。若AX的內容為正數,則擴展以后將0000送入DX;若AX的內容為負數,則擴展以后將0FFFF送入DX。

CBW指令和CWD指令格式中不帶操作數,隱含對AL、AX中的內容或對AX、DX中的內容進行的運算。

CWD指令的用法同CBW指令相同,與IDIV指令配合使用。不同之處是將16位的帶符號數變換成32位的帶符號數。10.6尋址與加、減法運算練習

這一節(jié)是對本章內容的練習,通過對例題的練習與上機操作,可幫助你加深了解CPU字節(jié)操作數和字操作數的尋址特點,掌握加、減運算指令的特點(只能進行二進制數的運算)。練習內容:

(1)字節(jié)與字的加、減法運算。

(2)多字節(jié)加法運算。10.6.1練習一:字節(jié)與字的加、減法運算1.程序架構1)數據段定義數據段:…BYTEADB64HBYTEBDB40HBYTECDB16HWORDADW4000HWDORBDW2000HWDROCDW1000H結束數據段:…2)指令段按程序架構定義段、過程:…程序按返回DOS的方式初始化:…CALLB10ADDCALLC10SUB程序按返回DOS的方式結束程序:…按程序架構結束過程:…;字節(jié)加法子程序—

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論