匯編語言各種指令的解釋與用法


數據傳輸指令

一、通用數據傳送指令
1、傳送指令 MOV (move)
指令的匯編格式:MOV DST,SRC
指令的基本功能:(DST)<-(SRC) 將原操作數(字節或字)傳送到目的地址。
指令支持的尋址方式:目的操作數和源操作數不能同時用存儲器尋址方式,這個限制適用於所有指令。指令的執行對標志位的影響:不影響標志位。
指令的特殊要求:目的操作數DST和源操作數SRC不允許同時為段寄存器;
目的操作數DST不能是CS,也不能用立即數方式。
2、進棧指令 PUSH (push onto the stack)
出棧指令 POP (pop from the stack)
指令的匯編格式:PUSH SRC ;POP DST
指令的基本功能:PUSH指令在程序中常用來暫存某些數據,而POP指令又可將這些數據恢復。PUSH SRC (SP)<-(SP)-2 ;(SP)<-(SRC)
POP DST (DST)<-((SP));(SP)<-(SP)
指令支持的尋址方式:push 和 pop指令不能不能使用立即數尋址方式。
指令對標志位的影響:PUSH 和 POP指令都不影響標志位。
指令的特殊要求:PUSH 和 POP指令只能是字操作,因此,存取字數據后,SP的修改必須是+2 或者 -2; POP指令的DST不允許是CS寄存器;
3、交換指令 XCHG (exchange)
指令的匯編格式:XCHG OPR1,OPR2
指令的基本功能:(OPR1)<->(OPR2)
指令支持的尋址方式:一個操作數必須在寄存器中,另一個操作數可以在寄存器或存儲器中。
指令對標志位的影戲:不影響標志位。
指令的特殊要求:不允許使用段寄存器。
二、累加器專用傳送指令
4、輸入指令 IN (input)
輸出指令 OUT (output)
指令的匯編格式:IN ac,port port<=0FFH
IN ac,DX port>0FFH
OUT port,ac port<=0FFH
OUT DX,ac port>0FFH
指令的基本功能:對8086及其后繼機型的微處理機,所有I/O端口與CPU之間的通信都由輸入輸出指令IN和OUT來完成。IN指令將信息從I/O輸入到CPU,OUT指令將信息從CPU輸出到I/O端口,因此,IN和OUT指令都要指出I/O端口地址。
IN ac,port port<=0FFH (AL)<-(port)傳送字節 或 (AX)<-(port+1,port)傳送字
IN ac,DX port>0FFH (AL)<-((DX))傳送字節或 (AX)<-((DX)+1,(DX))傳送字
OUT port,ac port<=0FFH (port)<-(AL)傳送字節 或 (port+1,port)<-(AX)傳送字
OUT DX,ac port>0FFH (DX)<-(AL)傳送字節 或 ((DX)+1,(DX))<-(AX)傳送字
指令對標志位的影響:不影響標志位。指令的特殊要求:只限於在AL或AX與I/O端口之間傳送信息。傳送16位信息用AX,傳送8位信息用AL,這取決於外設端口的寬度。
5、換碼指令 XLAT (translate)
指令的匯編格式:XLAT opr 或 XLAT
指令的基本功能:這條指令根據AL寄存器提供的位移量,將BX指使的字節表格中的代碼換存在AL中。 (AL)<-((DS)*16+(BX)+(AL))
指令對標志位的影響:不影響標志位。
指令的特殊要求:所建字節表格的長度不能超過256字節,因為存放位移量的是8位寄存器AL。opr為表格的首地址,因為opr所表示的偏移地址已存入BX寄存器,所以opr在換碼指令中可有可無,有則提高程序的可讀性。
三、地址傳送指令
6、有效地址傳送器 LEA (load effective address)
指令的匯編格式:LEA reg,src
指令的基本功能:LEA指令把源操作數的有效地址送到指定的寄存器,這個有效地址是由src選定的一種存儲器尋址方式確定的。
指令支持的尋址方式:各種存儲器尋址方式。
指令對標志位的影響:不影響標志位。
指令的特出要求:指令中reg不能是段寄存器;
7、指針送寄存器和DS LDS (load DS with point)
指針送寄存器和ES LES (load ES with point)
指令的匯編格式:LDS reg,src LES reg,src
指令的基本功能:LDS和LES指令把確定內存單元位置的偏移地址送寄存器,段地址DS或ES。這個偏移地址和段地址(也稱地址指針)是由src指定的兩個相繼字單元提供的。
LDS reg,src (reg)<-(src) (DS)<-(src+2)
LES reg,src (reg)<-(src) (ES)<-(src+2)
指令支持的尋址方式:src必須為存儲器尋址方式
指令對標志位的影響:不影響標志位。
指令的特殊要求:指令中REG不能是段寄存器;
四、標志寄存器傳送指令
8、標志寄存器的低字節送AH LAHF (load AH with FLAGS)
指令的匯編格式:LAHF
指令的基本功能:(AH)<-(FLAGS)0-7
指令對標志位的影響:不影響標志位
9、AH送標志寄存器低字節 SAHF(store AH into FLAGS)
指令的格式:SAHF
指令的基本功能:(FLAGS)0-7<-(AH)
指令對標志位的影響:由裝入值來確定標志位的值。
10、標志進棧 PUSHF (push the flags)
指令的匯編格式:PUSHF
指令的基本功能:(SP)<-(SP)-2 ((SP)+1,(SP))<-(FLAGS)0-15
指令對標志位的影響:不影響標志位。
11、標志出棧 POPF (pop the FLAGES)
指令的匯編格式:POPF
指令的基本功能:(FLAGS)0-15<-((SP)+1,(SP)) (SP)<-(SP)+2
指令對標志位的影響:由裝入值來確定標志位的值。

算術指令
一、加法指令
12、加法指令 ADD (addition)
指令的匯編格式:add dst,src
指令的基本功能:(dst)<-(src)+(dst)
指令支持的尋址方式:他們兩個操作數不能同時為存儲器尋址。即為除源操作數為立即數的情況外,源操作數和目地操作數必須有一個寄存器尋址方式。
指令對標志位的影響:SF=1 加法結果為負數(符號位為1)
SF=0 加法結果為正數(符號位為0)
ZF=1 加法結果為零
ZF=0 加法結果不為零
CF=1 最高有效位向高位有進位
CF=0 最高有效位向高位無進位
OF=1 兩個同符號數相加(正數+正數或負數+負數),結果符號與其相反。
OF=0 兩個不同符號數相加,或同符號數相加,結果符號與其相同。
13、帶進為加法指令 ADC (add with carry)
指令的匯編格式:ADD dst,src
指令的基本功能:(dst)<-(src)+(dst)+CF
指令支持的尋址方式:他們兩個操作數不能同時為存儲器尋址。即為除源操作數為立即數的情況外,源操作數和目地操作數必須有一個寄存器尋址方式。
指令對標志位的影響:SF=1 加法結果為負數
SF=0 加法結果為正數
ZF=1 加法結果為零
ZF=0 加法結果不為零
CF=1 最高有效位向高位有進位
CF=0 最低有效位相高位無進位
OF=1 兩個同符號數相加,結果符號與其相反,
OF=0 兩個同符號數相加,或同符號相加,結果符號與其相同
14、加1指令 INC (increament)
指令的匯編格式:INC opr
指令的基本功能:(opr)<-(opr)
指令支持的尋址方式 可以使用除立即數方式外的任何尋址方式
指令對標志位的影響:SF=1 加法結果為負數
SF=0 加法結果為正數
ZF=1 加法結果為零
ZF=0 加法結果不為零
OF=1 兩個同符號數相加,結果符號與其相反,
OF=0 兩個同符號數相加,或同符號相加,結果符號與其相同。
二、減法指令
15、減法指令 SUB (subtract)
指令的匯編格式:SUB dst,src
指令的基本功能:(dst)<-(dst)-(src)
指令支持的尋址方式:他們兩個操作數不能同時為存儲器尋址。即為除源操作數為立即數的情況外,源操作數和目地操作數必須有一個寄存器尋址方式。
指令對標志位的影響:SF=1 減法結果為負數(符號位為1)
SF=0 減法結果為正數(符號位為0)
ZF=1 減法結果為零
ZF=0 減法結果不為零
CF=1 二進制減法運算中最高有效位向高位有借位(被減數小於減數,不夠減的情況)
CF=0 二進制減法運算中最高有效為向高位無借位(被減數〉=減數,夠減的情況)
OF=1 兩數符號相反(正數-負數,或負數-正數),而結果符號與減數相同。
OF=0 同符號數相減時,或不同符號數相減,其結果符號與減數不同。
16、帶借位減法指令 SBB (subtract with borrow)
指令的匯編格式:SBB dst,src
指令的基本功能:(dst)<-(dst)-(src)-CF
指令支持的尋址方式:他們兩個操作數不能同時為存儲器尋址。即為除源操作數為立即數的情況外,源操作數和目地操作數必須有一個寄存器尋址方式。
指令對標志位的影響:SF=1 減法結果為負數(符號位為1)
SF=0 減法結果為正數(符號位為0)
ZF=1 減法結果為零
ZF=0 減法結果不為零
CF=1 二進制減法運算中最高有效位向高位有借位(被減數小於減數,不夠減的情況)
CF=0 二進制減法運算中最高有效為向高位無借位(被減數〉=減數,夠減的情況)
OF=1 兩數符號相反(正數-負數,或負數-正數),而結果符號與減數相同。
OF=0 同符號數相減時,或不同符號數相減,其結果符號與減數不同。
17、減1指令 DEC (decrement)
指令的匯編格式:DEC opr
指令的基本功能:(opr)<-(opr)-1
指令支持的尋址方式:可以使用除立即數方式外的任何尋址方式。
指令對標志位的影響:SF=1 減法結果為負數(符號位為1)
SF=0 減法結果為正數(符號位為0)
ZF=1 減法結果為零
ZF=0 減法結果不為零
OF=1 兩數符號相反(正數-負數,或負數-正數),而結果符號與減數相同。
OF=0 同符號數相減時,或不同符號數相減,其結果符號與減數不同。
18、比較指令 CMP (compare)
指令的匯編格式:CMP opr1,opr2
指令的基本功能:(opr1)-(opr2),根據相減結果設置條件碼,但不回送結果。
指令支持的尋址方式:他們兩個操作數不能同時為存儲器尋址。即為除源操作數為立即數的情況外,源操作數和目地操作數必須有一個寄存器尋址方式。
指令對標志位的影響:

SF=1 減法結果為負數(符號位為1)
SF=0 減法結果為正數(符號位為0)
ZF=1 減法結果為零
ZF=0 減法結果不為零
CF=1 二進制減法運算中

最高有效位向高位有借位(被減數小於減數,不夠減的情況)
CF=0 二進制減法運算中最高有效為向高位無借位(被減數〉=減數,夠減的情況)
OF=1 兩數符號相反(正數-負數,或負數-正數),而結果符號與減數相同。
OF=0 同符號數相減時,或不同符號數相減,其結果符號與減數不同。
19、求補指令 NEG (negate)
指令的匯編格式:NEG opr
指令的基本功能:(opr)<- -(opr)
指令支持的尋址方式:可以使用除立即數方式外的任何尋址方式。
指令對標志位的影響:CF=1  不為0的操作數求補時
    CF=0  為0的操作數求補時
OF=1 操作數為-128(字節運算)或操作數為-32768(字運算)
OF=0 當求補運算的操作數不為-128(字節)或-32768(字)時三、乘法指令
20、無符號乘法指令 NUL (unsigned multiple)
有符號乘法指令 IMUL(signed muliple)
指令的匯編格式:NUL src IMUL src
指令的基本功能:(AX)<-(AL)*(src) (DX,AX)<-(AX)*(src)
指令支持的尋址方式:src可以使用除立即數方式以外的任一種尋址方式。
指令對標志位的影響:乘法指令只影響標志位CF和OF,其他條件碼位無定義。
MUL指令的條件碼設置為:
CF OF=0 0 乘積的高一半為0(字節操作的(AH)或字操作的(DX))
CF OF=1 1 乘積的高一半不為0
IMUL指令的條件碼設置為:
CF OF=0 0 乘積的高一半為低一半的符號擴展.
CF OF=1 1 其他情況
指令的特殊要求:MUL和IMUL指令的區別僅在於操作數是無符號還是帶符號數,它們的共同點是,指令中只給出源操作數src,目的操作數是隱含的,它只能是累加器(字運算為AX,字節運算為AL)。隱含的乘積寄存器是AX或DX(高位)和AX(低位)。
四、符號擴展指令
21、節擴展為字 CBW (convert byte to word)
指令的匯編格式:CBW
指令的基本功能:(AH)=00H 當(AL)的最高有效位為0時
(AH)=FFH 當(AL)的最高有效位為1時
指令對標志位的影響:不影響標志位
指令的特殊要求:這是條無操作數的指令,進行符號擴展的操作數必須存放在AL寄存器 AX寄存器中。
22、字擴展為雙字 CWD (convert word to double word)
指令的匯編格式:CWD
指令的基本功能:(DX)=0000H 當(AX)的最高有效位為0時
(DX)=FFFFH 當(AX)的最高有效位為1時
指令對標志位的影響:不影響標志位
指令的特殊要求:這是條無操作數的指令,進行符號擴展的操作數必須存放在AL寄存器或AX寄存器中。
五、除法指令
23、無符號數除法 DIV (unsigned divide)
帶符號數除法 IDIV (singed divide)
指令的匯編格式:DIV src IDIV src
指令的基本功能:字操作
(AL)<-(AX)/src的商 (AH)<-(AX)/src的余數
字節操作
(AX)<-(DX,AX)/src的商 (DX)<-(DX,AX)/src的余數
指令支持的尋址方式:src作為除數,可用除立即數以外的任一種尋址方式來取得。
指令對標志位的影響:不影響條件碼。
指令的特殊要求:除法指令要求字操作時,被除數必須為32位,除數是16位,商和余數是16位的;字節操作時,被除數必須為16位,除數是8位,得到的商和余數是8位的。

六、十進制調整指令

邏輯指令


一、邏輯運算
指令的格式:AND dst,src
指令的基本功能:(dst)<-(dst)與(src)
指令支持的尋址方式:兩個操作數不能同時為存儲器尋址。即為除源操作數為立即數的情況外,源操作數和目地操作數必須有一個寄存器尋址方式。
指令對標志位的影響:指令執行后 CF 和 OF 置零,AF無定義。
SF=1 指令執行后的結果為負數(符號位為1)
SF=0 指令執行后的結果為正數(符號位為0)
ZF=1 指令執行后的結果為零
ZF=0 指令執行后的結果不為零
PF=1 結果操作數中1的個數為偶數時置1
PF=0 結果操作數中1的個數為奇數時置0
25、邏輯或 OR (logic or)
指令的匯編格式:OR dst,src
指令的基本功能:(dst)<-(dst)或(src)
指令支持的尋址方式:兩個操作數不能同時為存儲器尋址。即為除源操作數為立即數的情況外,原操作數和目的操作數必須有一個寄存器尋址方式。
指令對標志位的影響:令執行后 CF 和 OF 置零,AF無定義。
SF=1 指令執行后的結果為負數(符號位為1)
SF=0 指令執行后的結果為正數(符號位為0)
ZF=1 指令執行后的結果為零
ZF=0 指令執行后的結果不為零
PF=1 結果操作數中1的個數為偶數時置1
PF=0 結果操作數中1的個數為奇數時置0
26、邏輯非 NOT (logic not)
指令的匯編格式:NOT orc
指令的基本功能:(dst)<-(opr)
指令支持的尋址方式:除立即數尋址方式以外的其余尋址方式
指令對標志位的影響:對標志位無影響
27、異或 XOR (exclusice or)
指令的匯編格式:XOR dst,src
指令的基本功能:(dst)<-(dst)異或(src)
指令支持的尋址方式:兩個操作數不能同時為存儲器尋址。即為除源操作數為立即數的情況外,原操作數和目的操作數必須有一個寄存器尋址方式。
指令對標志位的影響:令執行后 CF 和 OF 置零,AF無定義。
SF=1 指令執行后的結果為負數(符號位為1)
SF=0 指令執行后的結果為正數(符號位為0)
ZF=1 指令執行后的結果為零
ZF=0 指令執行后的結果不為零
PF=1 結果操作數中1的個數為偶數時置1
PF=0 結果操作數中1的個數為奇數時置0
28、測試指令 TEST
指令的匯編格式:TEST opr1,opr2
指令的基本功能:(opr1)與(opr2)
指令支持的尋址方式:兩個操作數不能同時為存儲器尋址,即為除源操作數為立即數的情況外,源操作數和目的操作數必須有一個寄存器尋址方式。
指令對標志位的影響:令執行后 CF 和 OF 置零,AF無定義。
SF=1 指令執行后的結果為負數(符號位為1)
SF=0 指令執行后的結果為正數(符號位為0)
ZF=1 指令執行后的結果為零
ZF=0 指令執行后的結果不為零
PF=1 結果操作數中1的個數為偶數時置1
PF=0 結果操作數中1的個數為奇數時置0
二、移位指令
29、邏輯左移 SHL (shift logical left)
指令的匯編格式:SHL dst,cnt
指令的基本功能:SHL指令向左逐位移動cnt次,每次逐位移動后,最低位用0來補充,最高位移入CF。
指令支持的尋址方式:目的操作數dst可以是除立即數外的任何尋址方式。移位次數(或位數)cnt=1時,1可以直接寫在指令中,cnt〉1時,cnt必須放入CL寄存器中。
指令對標志位的影響:CF=移入的數值
OF=1 當cnt=1時,移動后最高位的值發生變化。
OF=0 當cnt=1時,移動時最高位的值未發生變化。
SF、ZF、PF根據移動后的結果設置

30、邏輯右移 SHR (shift logical right)
指令的匯編格式:SHR dst,cnt
指令的基本功能:SHR指令向右逐位移動cnt次,每次逐位移動后,最高位用0來補充,最低位移入CF。
指令支持的尋址方式:目的操作數dst可以是除立即數外的任何尋址方式。移位次數(或位數)cnt=1時,1可以直接寫在指令中,cnt〉1時,cnt必須放入CL寄存器中。
指令對標志位的影響:CF=移入的數值
OF=1 當cnt=1時,移動后最高位的值發生變化。
OF=0 當cnt=1時,移動時最高位的值未發生變化。
SF、ZF、PF根據移動后的結果設置。
31、算術左移 SAL (shift arithmetic left)
指令的匯編格式:SAL dst cnt
指令的基本功能:SAL指令向左逐位移動cnt次,每次逐位移動后,最低位用0來補充,最高位移入CF。
指令支持的尋址方式:目的操作數dst可以是除立即數外的任何尋址方式。移位次數(或位數)cnt=1時,1可以直接寫在指令中,cnt〉1時,cnt必須放入CL寄存器中。
指令對標志位的影響:CF=移入的數值
OF=1 當cnt=1時,移動后最高位的值發生變化。
OF=0 當cnt=1時,移動時最高位的值未發生變化。
SF、ZF、PF根據移動后的結果設置。
32、算術右移 SAR (shift arithmetic right)
指令的匯編格式:SAR dst,cnt
指令的基本功能:SAR指令向右逐位移動cnt次,每次逐位移動后,最高位用符號位來補充,最低位移入CF。
指令支持的尋址方式:目的操作數dst可以是除立即數外的任何尋址方式。移位次數(或位數)cnt=1時,1可以直接寫在指令中,cnt〉1時,cnt必須放入CL寄存器中。
指令對標志位的影響:CF=移入的數值
OF=1 當cnt=1時,移動后最高位的值發生變化。
OF=0 當cnt=1時,移動時最高位的值未發生變化。
SF、ZF、PF根據移動后的結果設置。
33、循環左移 ROL (rotate left)
指令的匯編格式:ROL dst,cnt
指令的基本功能:ROL 對由dst指定的寄存器或存儲器操作數左移循環移動cnt所指定的次數,每左移一次,把最高位同時移入CF和操作數最低位。
指令支持的尋址方式:目的操作數dst可以是除立即數外的任何尋址方式。移動次數(或位數)cnt=1時,1可以直接寫在指令中,cnt〉1時,cnt必須放入CL寄存器中。
指令對標志位的影響:CF=移入的數值
OF=1 當cnt=1時,移動后最高位的值發生變化。
OF=0 當cnt=1時,移動時最高位的值未發生變化。
SF、ZF、PF根據移動后的結果設置。
34、循環右移 ROR (rotate right)
指令的匯編格式:ROR dst,cnt
指令的基本功能:ROR 對由dst指定的寄存器或存儲器操作數右移循環移動cnt所指定的次數,每右移一次,把最低位同時移入CF和操作數最高位。
指令支持的尋址方式:目的操作數dst可以是除立即數外的任何尋址方式。移動次數(或位數)cnt=1時,1可以直接寫在指令中,cnt>1時,cnt必須放入CL寄存器中。
指令對標志位的影響:CF=移入的數值
OF=1 當cnt=1時,移動后最高位的值發生變化。
OF=0 當cnt=1時,移動時最高位的值未發生變化。
SF、ZF、PF根據移動后的結果設置。
35、帶進位的循環左移 RCL (rotate left through carry)
指令的匯編格式:RCL dst,cnt
指令的基本功能:RCL 對由dst指定的寄存器或存儲器操作數,連同進位標志CF左循環移動,m所指定的次數,每左移一次,把操作數的最高位移入CF,而CF中原有內容移入操作數的最低位。
指定支持的尋址方式:目的操作數dst可以是除立即數外的任何尋址方式。移動次數(或位數)cnt=1時,1可以直接寫在指令中,cnt〉1時,cnt必須放入CL寄存器中。
指令對標志位的影響:CF=移入的數值。
OF=1 當cnt=1時,移動后最高位的值未發生變化。
OF=0 當cnt=1時,移動后最高位的值發生變化。
SF、ZF、PF標志位不受影響。
36、帶進位的循環右移 RCR (rotate right through carry)
指令的匯編格式:RCR dst,cnt
指令的基本功能:RCR 對由dst指定的寄存器或存儲器操作數,連同進位標志CF右循環移動,m所指定的次數,每右移一次,把操作數的最高低位移入CF,而CF中原有內容移入操作數的最高位。
指令支持的尋址方式:目的操作數dst可以是除立即數外的任何尋址方式。移動次數(或位數)cnt=1時,1可以直接寫入指令中,cnt〉1時,cnt必須放入CL寄存器中。
指令對標志位的影響:CF=移入的數值。
OF=1 當cnt=1時,操作數最高位的值未發生變化。
OF=0 當cnt=1時,操作數最高位的值發生變化。
SF、ZF、PF標志位不受影響。

【串處理指令】


一、設置方向標志指令
37、DF置零 CLD (clear direction flag)
DF置一 STD (set direction flag)
指令的匯編格式:CLD
STD
指令的基本功能:CLD DF=0
STD DF=1
二、串處理指令
38、串傳送 MOVSB / MOVSW (move string byte/word)
指令的匯編格式:MOVSB
MOVSW
指令的基本功能:(ES:DI)<-(DS:SI)
(SI)<-(SI)+/-1(字節)或+/-2(字)
(DI)<-(DI)+/-1(字節)或+/-2(字)
指令對條件碼的影響:不影響條件碼。
指令的特殊要求:源串必須在數據段中,目的串必須在附加段中,串處理指令隱含的尋址方式是SI和DI寄存器的間接尋址方式。源串允許使用段跨越前綴來指定段。
39、存串 STOSB / STOSW (stroe from string byte/word)
指令的匯編格式:STOSB
STOSW
指令的基本功能:(ES:DI)<-(AL)或(AX)
(DI)<-(DI)+/-1(字節)或+/-2(字)
指令對條件碼的影響:不影響條件碼。
指令的特殊要求:源串必須在數據段中,目的串必須在附加段中,串處理指令隱含的尋址方式是SI和DI寄存器的間接尋址方式。源串允許使用段跨越前綴來指定段。
40、取串LODSB / LODSW (load from string byte/word)
指令的匯編格式:LODSB
LODSW
指令的基本功能:(AL)或(AX)<-(DS:SI)
(SI)<-(SI)+/-1(字節)或+/-2(字)
指令對條件碼的影響:不影響條件碼。
指令的特殊要求:源串必須在數據段中,目的串必須在附加段中,串處理指令隱含的尋址方式是SI和DI寄存器的間接尋址方式。源串允許使用段跨越前綴來指定段。
41、串比較 CMPSB / CMPSW (compare string byte/word)
指令的匯編格式:CMPSB
CMPSW
指令的基本功能:(DS:SI)-(ES:DI) 根據比較結果設置條件碼
(SI)<-(SI)+/-1(字節)或+/-2(字)
(DI)<-(DI)+/-1(字節)或+/-2(字)
指令對條件碼的影響:SF=1 減法結果為負數(符號位為1)
SF=0 減法結果為正數(符號位為0)
ZF=1 減法結果為零
ZF=0 減法結果不為零
CF=1 二進制減法運算中最高有效位向高位有借位(被減數小於減數,不夠減的情況)
CF=0 二進制減法運算中最高有效為向高位無借位(被減數〉=減數,夠減的情況)
OF=1 兩數符號相反(正數-負數,或負數-正數),而結果符號與減數相同。
OF=0 同符號數相減時,或不同符號數相減,其結果符號與減數不同。
42、串掃描 SCASB / SCASW (scan string byte / word)
指令的格式:SCASB
SCASW
指令的基本功能:(AL)<-(ES:DI)或(AX)<-(ES:DI) 根據掃描比較的結果設置條件碼。
(DI)<-(DI)+/-1(字節)或+/-2(字)
指令對條件碼的影響:SF=1 結果為負數(符號位為1)
SF=0 結果為正數(符號位為0)
ZF=1 結果為零
ZF=0 結果不為零
CF=1 二進制減法運算中最高有效位向高位有借位(被減數小於減數,不夠減的情況)
CF=0 二進制減法運算中最高有效為向高位無借位(被減數〉=減數,夠減的情況)
OF=1 兩數符號相反(正數-負數,或負數-正數),而結果符號與減數相同。
OF=0 同符號數相減時,或不同符號數相減,其結果符號與減數不同。
三、串重復前綴
43、重復執行串 REP 
指令的匯編格式:REP (CX)=重復次數
指令的基本功能:① (CX)=0時,串指令執行完畢,否則執行② ~ ④
② (CX)←(CX)-1③ 執行串指令(MOVS或STOS)④ 重復執行①
44、相等/為零時重復執行串指令 REPE/REPZ
指令的匯編格式:REPE / REPZ (CX)=比較/掃描的次數
指令的基本功能:① (CX)=0或ZF=0時,結束執行串指令,否則繼續② ~ ④
② (CX)←(CX)-1③ 執行串指令(CMPS或SCAS)④ 重復執行①
45、不等/不為零時重復執行串指令 REPNE / PEPNZ
指令的匯編格式:REPNE / PEPNZ (CX)=比較/掃描的次數
指令的基本功能:① (CX)=0或ZF=1,結束執行串指令,否則繼續② ~ ④
② (CX)←(CX)-1③ 執行串指令(CMPS或SCAS)④ 重復執行①

【控制轉移指令】


一、無條件轉移指令
46、短轉移 JMP SHORT label (short jump)
指令的匯編格式:JMP SHORT label
指令的基本功能:(IP)<-當前(IP)+8位位移量 8位位移量是匯編程序在匯編源程序時,根據目標地址和當前IP之間的距離自動生成的。
指令對條件碼的影響:對標志位無影響。
47、近轉移 JMP NEAR PTR label (near jump)
指令的匯編格式:直接轉移 JMP label (direct jump)
寄存器間接轉移 JMP reg (register indirect jump)
存儲器間接轉移 JMP WORD PTR OPR (memory indirect jump)
指令的基本功能:JMP label (IP) <- OFFSET label = (IP)當前+16位位移量
JMP reg (IP) <- (reg)
JMP WORD PTR OPR (IP) <- (PA+1,PA)
指令支持的尋址方式:指令中的轉向地址可以是直接尋址方式、寄存器尋址方式、寄存器間接尋址方式和存儲器尋址方式。
指令對條件碼的影響:對標志位無影響。
48、遠轉移 JMP FAR PTR label (for jump)
指令的匯編格式:JMP FAR PTR label
指令的基本功能:(IP)<-label的段內偏移地址 (CS)<-label所在段的段地址
指令支持的尋址方式:遠轉移的目的地址可以使用除立即尋址方式外的任何尋址方式來表示。指令對條件碼的影響:對標志位無影響。
二、條件轉移指令
指令的匯編格式及功能
根據條件碼的值轉移:
49、JZ(JE) OPR ZF=1                            ZF=0(運算結果為0,ZF就置1)
50、JNZ(JNE) OPR ZF=0
51、JS OPR SF=1                                 SF=0(二進制最高位是什么,SF就是什么,如最高位為1則SF=1)
52、JNS OPR SF=0
53、JO OPR OF=1                                OF=1 (兩個負數相加變成正數,溢出) 
54、JNO OPR OF=0
55、JP OPR PF=1                                 PF=0 (反映結果“1”的個數,奇數☞0 偶數個☞1)
56、JNP OPR PF=0
57、JC OPR CF=1                                 CF=1(最高位有進位或借位就置1)
58、JNC OPR CF=0
比較兩個無符號數,根據比較的結果轉移
59、JB(JNAE,JC) OPR CF=1 被減數小於減數則轉移
60、JNB(JAE,JNC) OPR CF=0 被減數大於或等於減數則轉移
61、JBE(JNA) OPR CF或ZF=1 被減數小於或等於減數則轉移
62、JNBE(JA) OPR CF或ZF=0 被減數大於減數則轉移
比較兩個帶符號數,根據比較結果轉移
63、JL/JNGE OPR SF異或OF=1 被減數小於減數則轉移
64、JNL/JGE SF異或OF=0 被減數不小於減數則轉移
65、JLE/JNE (SF異或OF)與ZF=1 被減數不大於減數則轉移
66、JNLE/JG (SF異或OF)與ZF=0 被減數大於減數則轉移
根據CX寄存器的值轉移
67、JCXZ (CX)=0 CX內容為零則轉移
指令的特殊要求:所有條件轉移指令都是短轉移指令,轉移的目標地址必須在當前IP地址的-128至+127字節范圍之內,因此條件轉移指令是2字節指令。
三、循環指令
68、循環 LOOP (loop)
指令的匯編格式:LOOP label
指令的基本功能:① (CX)←(CX)-1 ② 若(CX)≠0,則(IP)←(IP)當前+位移量,否則循環結束。
指令的特殊要求:循環指令都是短轉移格式的指令,也就是說,位移量是用8位帶符號數來表示的,轉向地址在相對於當前IP值的-128 ~ +127字節范圍之內。
69、為零/相等時循環 LOOPZ/LOOPE (loop while nonzero or equal)
指令的匯編格式:LOOPNZ/LOOPNE label
指令的基本功能:① (CX)←(CX)-1
        ② 若ZF=1且(CX)≠0,則(IP)←(IP)當前+位移量,否則循環結束。
指令的特殊要求:循環指令都是短轉移格式的指令,也就是說,位移量是用8位帶符號數來表示的,轉向地址在相對於當前IP值的-128 ~ +127字節范圍之內。
70、不為零/不相等時循環 LOOPNZ/LOOPNE (loop while nonzero or not equal)
指令的匯編格式:LOOPNZ/LOOPNE label
指令的基本功能:① (CX)←(CX)-1
        ② 若ZF=0且(CX)≠0,則(IP)←(IP)當前+位移量,否則循環結束。
指令的特殊要求:循環指令都是短轉移格式的指令,也就是說,位移量是用8位帶符號數來表示的,轉向地址在相對於當前IP值的-128 ~ +127字節范圍之內。
四、子程序調用
71、段內直接近調用 CALL SUBROUT
指令的基本功能:(SP)<-(SP)-2
((SP)+1,(sp))<-(IP)
(IP)<-(IP)+16位位移量
段內間接近調用 CALL DESTIN
指令的基本功能:(SP)<-(SP)-2
((SP)+1,(SP))<-(IP)
(IP)<-(EA)
72、段間直接調用 CALL FAR PTR SUBROUT
指令的基本功能:(SP)<-(SP)-2,((SP))<-(CS)當前
(SP)<-(SP)-2,((SP))<-(IP)當前
(IP)<-偏移地址(在指令的第2、3個字節)
(CS)<-段地址(在指令的第4、5個字節)
五、返回指令
73、段內返回(近返回) RET
指令的基本功能:(IP)<-((SP)+1,(SP))
(SP)<-(SP)+2
段間返回(遠返回) RET
指令的基本功能:(IP)<-((SP)),(SP)<-(SP)+2
(CS)<-((SP)),(SP)<-(SP)+2
帶立即數返回 RET N
執行操作:① 返回地址出棧(操作同段內或段間返回)

② 修改堆棧指針:(SP) ← (SP)+N
六、中斷及中斷返回指令
74、INT n 中斷指令(interrupt),n為中斷類型號
  執行操作:① 入棧保存FLAGS:(SP) ← (SP)-2,((SP)) ← (FLAGS)
       ② 入棧保存返回地址:(SP) ← (SP)-2,((SP)) ← (CS)
                  (SP) ← (SP)-2,((SP)) ← (IP)
       ③ 轉中斷處理程序:(IP) ← (n×4)
                 (CS) ← (n×4+2)
75、IRET 中斷返回指令(return from interrupt)
  執行操作:① 返回地址出棧:(IP) ← ((SP)),(SP) ← (SP)+2
                (CS) ← ((SP)),(SP) ← (SP)+2
       ② FLAGS出棧:(FLAGS) ← ((SP)),(SP) ← (SP)+2
76、INTO 溢出則中斷(中斷類型為4)
  執行操作:若OF=1(有溢出),則:
       ① 入棧保存FLAGS:(SP) ← (SP)-2,((SP)) ← (FLAGS)
       ② 入棧保存返回地址:(SP) ← (SP)-2,((SP)) ← (CS)
                  (SP) ← (SP)-2,((SP)) ← (IP)
       ③ 轉中斷處理程序:(IP) ← (4×4)= (10H)
                 (CS) ← (4×4+2)= (12H

HELLO,WORLD進階匯編程序系列

 

 Editor:admin  Time:2004-3-21 12:49  Read:9785  Score:8  Print

 Writer:LLUCT

 Excerpt:80x86匯編小站  

 

 Preface:

感謝網友lluct為本站提供原創......適合初學者學習哦  

 

 Content:

TITLE   ***HELLO,WORLD進階程序之選擇分支 BY LLUCT***

 

DATA    SEGMENT   ;定義數據段

MSG1    DB      '***WELCOME TO MY PROGRAM BY LLUCT***','$'

;定義輸出的第一個字符串信息,字符串必須用DB定義,$為結束標志

MSG2    DB      '1:BASIC MESSAGE 2:ADVANCED MESSAGE','$'

;定義輸出的字符串信息:選擇菜單

MSG3    DB      'PLEASE CHOOSE:','$'

;定義輸出的字符串信息:選擇前綴

MSG4    DB      'HELLO,WORLD!^-^','$'

;定義輸出的字符串信息:分支1的信息

MSG5    DB      'THIS IS MY FIRST ASM_86 PROGRAM! @^-^@','$'

;定義輸出的字符串信息:分支2的信息

ERRMSG  DB      'CHOOSE ERROR! -_-b','$'

;定義輸出的字符串信息:選擇錯誤信息

DATA    ENDS   ;數據段結尾

 

CODE    SEGMENT   ;定義代碼段

        ASSUME  CS:CODE  ;規定CS的內容

        ASSUME  DS:DATA  ;規定DS的內容

 

START:  MOV     AX,DATA  ;程序從START開始

        MOV     DS,AX  ;DS置初值,DATA的段地址

 

        CALL ENTER  ;調用顯示回車換行子程序

 LEA     DX,MSG1  ;輸出第一個字符串的偏移地址

        CALL DISPCHS  ;調用顯示字符串子程序

        CALL    ENTER  ;調用顯示回車換行子程序

        CALL    ENTER  ;這個...同上啊^-^

 

        LEA     DX,MSG2  ;輸出第二個字符串的偏移地址

        CALL DISPCHS  ;調用顯示字符串子程序

 

AGAIN:  CALL    ENTER  ;定義AGAIN標號.用於選擇錯誤循環

 

        LEA     DX,MSG3  ;輸出第三個字符串的偏移地址

        CALL DISPCHS  ;調用顯示字符串子程序

 

        MOV     AH,01H  ;調用1號功能:從鍵盤輸入一個字符並回顯

        INT     21H  ;完成輸入回顯

        CMP     AL,'1'  ;輸入的字符和1相比較

        JE      BASICP  ;如果相等,轉移到BASICP標號(JE=Jump if Equal)

        CMP     AL,'2'  ;輸入的字符和2相比較             ||

        JE      ADVANP  ;如果相等,轉移到ADVANP標號(JE=如果相等就轉移)

        JMP     ERROR  ;否則就無條件轉移到ERROR標號

 

EXIT:   MOV     AH,4CH  ;4C號功能調用:終止當前程序並返回調用程序

        INT     21H  ;返回DOS

 

BASICP: CALL    ENTER  ;什么,還要解釋啊.暈-_-!!!

        LEA     DX,MSG4  ;輸出第三個字符串的偏移地址

        CALL DISPCHS  ;調用顯示字符串子程序

        CALL    ENTER  ;..........

        JMP     EXIT  ;無條件轉移到EXIT標號

 

ADVANP: CALL    ENTER  ;55555555

        LEA     DX,MSG5  ;解釋了四次,應該懂了吧

        CALL DISPCHS  ;調用顯示字符串子程序

        CALL    ENTER  ;再問就死給你看

        JMP     EXIT  ;無條件轉移到EXIT標號

 

ERROR:  CALL    ENTER

        LEA     DX,ERRMSG ;輸出選擇錯誤信息

        CALL DISPCHS  ;調用顯示字符串子程序

        MOV DL,07H  ;輸出ASCII碼的報警(響鈴)控制符BEL(07H)

 CALL DISPCH  ;調用顯示單個字符子程序

 CALL    ENTER

        JMP     AGAIN

 

DISPCH  PROC    NEAR  

;顯示單個字符子程序,NEAR說明子程序和主程序在同一個代碼段中(現無主程序調用)

        MOV     AH,02H  ;2號功能調用:顯示器輸出字符

        INT     21H  ;完成輸出顯示

        RET   ;返回

DISPCH  ENDP   ;子程序結尾

 

ENTER   PROC    NEAR  ;顯示回車換行子程序

        MOV     DL,0DH  ;輸出ASCII碼的回車控制符CR(0DH)

        CALL    DISPCH  ;調用顯示單個字符子程序

        MOV     DL,0AH  ;輸出ASCII碼的換行控制符LF(0AH)

        CALL    DISPCH  ;調用顯示單個字符子程序

        RET   ;返回

ENTER   ENDP   ;子程序結尾

 

DISPCHS PROC NEAR

;顯示字符串子程序,NEAR說明子程序和主程序在同一個代碼段中(現無主程序調用)

 MOV AH,09H  ;9號功能調用:顯示字符串

 INT 21H  ;完成輸出顯示

 RET

DISPCHS ENDP

 

CODE    ENDS   ;代碼段結尾

        END     START  ;結束匯編

 

;把以上代碼復制到記事本等文本程序中,並保存.(如helloch.asm)

;編譯:masm helloch.asm

;連接:link helloch.obj

;執行:helloch.exe

 

======================================================

 

title ***hello,world進階之字符串輸入輸出 by lluct***

 

 

data    segment   ;定義數據段

input   db      100 dup(?)

;定義輸入的字符串,字符串必須用db定義,長度為100個字節

msg1    db      'Hello,','$'

;定義輸出的前綴字符串信息,字符串必須用db定義,$為結束標志(24h)

msg2    db      ',Welcome to here!','$'

;定義輸出的后綴字符串信息

headmsg db      'PLEASE INPUT YOUR NAME:','$'

;開始顯示的字符串信息

data    ends   ;數據段結尾

 

code    segment   ;定義代碼段

        assume  cs:code  ;規定cs的內容

        assume  ds:data  ;規定ds的內容

 

start:  mov     ax,data  ;程序從start開始

        mov     ds,ax  ;ds置初值,data的段地址

        mov     si,0  ;變址寄存器置初值0

 

        call    enter  ;調用顯示回車換行子程序

        lea     dx,headmsg ;輸出開始顯示的字符串的偏移地址

        call    dispchs  ;調用顯示字符串子程序

repeat: mov     ah,01h  

;定義repeat標號,用於循環輸入單個字符.調用1號功能:從鍵盤輸入一個字符並回顯

        int     21h  ;完成輸入回顯

        cmp     al,0dh  ;輸入的字符和CR(回車)比較

        je      exit  ;如果等於回車就轉移到exit

        mov     input[si],al ;把al的值傳送到input的si地址中(好像是這樣吧)

        inc     si  ;si加1

        jmp     repeat  ;無條件轉移到repeat

 

exit:   call    enter

        mov     input[si],24h ;給輸入完成的字符串加上結束標志($)

        call    enter  

        lea     dx,msg1  ;輸出前綴字符串的偏移地址

        call    dispchs  ;調用顯示字符串子程序

        lea     dx,input ;輸出剛才輸入的字符串

        call    dispchs  

        lea     dx,msg2

        call    dispchs

        call    enter

        

 

        mov     ah,4ch  ;4c號功能調用:終止當前程序並返回調用程序

        int     21h  ;返回dos

 

enter   proc    near  ;顯示回車換行子程序

        mov     dl,0dh  ;輸出ascii碼的回車控制符cr(0dh)

        call    dispch  

        mov     dl,0ah  ;輸出ascii碼的換行控制符lf(0ah)

        call    dispch

        ret   ;返回

enter   endp   ;子程序結束

 

dispch  proc    near

        mov     ah,02h  ;2號功能調用:顯示器輸出字符

        int     21h  ;完成輸出顯示

        ret   ;返回

dispch  endp

 

dispchs proc    near

        mov     ah,09h  ;9號功能調用:顯示字符串

        int     21h  ;完成輸出顯示

        ret   ;返回

dispchs endp

 

code    ends   ;代碼段結尾

        end     start  ;結束匯編

 

;把以上代碼復制到記事本等文本程序中,並保存.(如heinout.c)

;編譯:masm heinout.asm

;連接:link heinout.obj

;執行:heinout.exe

 

中斷是指CPU對系統發生的某個事件作出的一種反應:CPU暫停正在執行的程序,保留現場后自動轉去執行相應的處理程序,處理完該事件后再返回斷點繼續執行被"打斷"的程序

在我們所用的電腦中,所有的硬件都需要執行中斷請求的動作,簡單說它的作用就是用來停止其相關硬件的工作狀態。我們可以舉一個日常生活中的例子來說明,假如你正在給朋友寫信,電話鈴響了,這時你放下手中的筆去接電話,通話完畢再繼續寫信。這個例子就表現了中斷及其處理的過程:電話鈴聲使你暫時中止當前的工作,而去處理更為急需處理的事情——接電話,當把急需處理的事情處理完畢之后,再回過頭來繼續原來的事情。在這個例子中,電話鈴聲就可以稱為“中斷請求”,而你暫停寫信去接電話就叫作“中斷響應”,那么接電話的過程就是“中斷處理”。由此我們可以看出,在計算機執行程序的過程中,由於出現某個特殊情況(或稱為“事件”),使得系統暫時中止現行程序,而轉去執行處理這一特殊事件的程序,處理完畢之后再回到原來程序的中斷點繼續向下執行,而這個過程就被稱為中斷。

 

中斷的作用

 

我們可以再舉一個例子來說明中斷的作用。假設有一個朋友來拜訪你,但是由於不知何時到達,你只能在門口等待,於是什么事情也干不了;但如果在門口裝一個門鈴,你就不必在門口等待而可以在家里去做其他的工作,朋友來了按門鈴通知你,這時你才中斷手中的工作去開門,這就避免了不必要的等待。而計算機也一樣,例如打印文稿的操作。因為cpu傳送數據的速度高,而打印機速度較慢,如果不采用中斷技術,cpu將經常處於等待狀態,這會使得電腦的工作效率極低。而采用了中斷方式后,cpu就可以在打印的同時進行其他的工作,而只在打印機緩沖區內的當前內容打印完畢,而發出中斷請求之后才予以響應,這時才暫時中斷當前的工作轉去執行停止打印的操作,之后再返回執行原來的程序。這樣就大大地提高了計算機系統的效率。

 

irq中斷

 

計算機中的中斷有好幾種,根據中斷信號產生的來源可以分為:硬件中斷和軟件中斷。硬件中斷多由外圍設備和計算機系統控制器發出,軟件中斷一般由軟件命令產生。在硬件中斷中又有“可屏蔽中斷”和“不可屏蔽中斷”之分。顧名思義,可屏蔽中斷可以由計算機根據系統的需要來決定是否進行接收處理或是延后處理(即屏蔽),而不可屏蔽中斷便是直接激活相應的中斷處理程序,它不能也不會被延誤。而irq中斷就是可屏蔽的硬件中斷,它的全稱為interrupt request 即“中斷請求”。

 

在電腦的系統中,是由一個中斷控制器8259或是8259a的芯片(現在此芯片大都集成到其他的芯片內)來對系統中每個硬件的中斷進行控制。目前共有16組irq,去掉其中用來作橋接的一組irq,實際上只有15組irq可供硬件調用。而這些irq都有自己建議的配置。

 

分配irq中斷

 

我們日常所用的操作系統對於irq的設置也不盡相同,所以在安裝新硬件的時候,系統往往並不能自動檢測正確的irq來分配給所需調用的硬件,這就會造成此硬件設備或是原來的舊硬件出現不能正常工作的現象。其實這是系統自動將該硬件的irq分配給了其他與此irq相同的硬件上,從而發生沖突使硬件不能正常工作。一般如果遇到這種情況,只要將新舊兩個硬件的irq配置手動調開就可以解決了。

 

對於一些常用的硬件一般都有其默認的irq數值。比如聲卡常常使用irq5或7。雖然這些配件使用其他的irq值大多數也能工作,但假如碰到特別“挑剔”的軟件或游戲等程序,例如只能識別irq值為5或7的聲卡,那么如果將它設成irq9就白費心機了。

8.3.1 中斷的基本概念
   中斷(Interrupt)是指計算機在實行期間,系統內發生非尋常的或非預期的急需處理事件,使得CPU暫時中斷當前正在執行的程序而轉去執行響應的事件處理程序。待處理完畢后又返回原來中斷處繼續執行或調度新的程序執行的過程。

   現代計算機系統一般都具有處理突發事件的能力。例如:從磁帶上讀入一組信息,當發現讀入信息有錯誤時,只要讓磁帶退回重讀該組信息就可能克服錯誤,而得到正確的信息。

   這種處理突發事件的能力是由硬件和軟件協作完成的。首先由硬件的中斷裝置發現產生的事件,然后,中斷裝置中止現行程序的執行,引出處理該事件的程序來處理。計算機系統不僅可以處理由於硬件或軟件錯誤而產生的事件,而且可以處理某種預定處理偽事件。例如:外圍設備工作結束時,也發出中斷請求,向系統報告它已完成任務,系統根據具體情況作出相應處理。引起中斷的事件稱為中斷源。發現中斷源並產生中斷的硬件稱中斷裝置。在不同的硬件結構中,通常有不同的中斷源和平不同的中斷裝置,但它們有一個共性,即:當中斷事件發生后,中斷裝置能改變處理器內操作執行的順序。

  中斷源:引起中斷發生的事件被稱為中斷源。
  中斷請求:中斷源向CPU發出的請求中斷處理信號。
  中斷響應:CPU收到中斷請求后轉相應的事件處理程序。
  禁止中斷(關中斷):CPU內部的處理機狀態字PSW的中斷允許位已被清除,不允許CPU響應中斷。
  開中斷:PSW的中斷允許位的設置。
  中斷屏蔽:在中斷請求產生之后,系統用軟件方式有選擇地封鎖部分中斷而允許蓁部分的中斷仍能得到響應。

8.3.4 中斷處理過程

  中斷處理過程:
   (1) CPU檢查響應中斷的條件是否滿足。CPU響應中斷的條件是:有來自於中斷源的中斷請求、CPU允許中斷。如果中斷響應條件不滿足,則中斷處理無法進行。
   (2) 如果CPU響應中斷,則CPU關中斷,使其進入不可再次響應中斷的狀態。
   (3) 保存被中斷進程現場。為了在中斷處理結束后能使進程正確地返回到中斷點,系統必須保存當前處理機狀態字PSW和程序計數器PC等的值。這些值一般保存在特定堆棧或硬件寄存器中。
   (4) 分析中斷原因,調用中斷處理子程序。在多個中斷請求同時發生時,處理優先級最高的中斷源發出的中斷請求。
   (5) 執行中斷處理子程序。對陷阱來說,在有些系統中則是通過陷阱指令向當前執行進程發軟中斷信號后調用對應的處理子程序執行。
   (6) 退出中斷,恢復被中斷進程的現場或調度新進程占據處理機。
   (7) 開中斷,CPU繼續執行。

1.什么叫中斷?
  簡單來說,中斷是一種使CPU中止正在執行的程序而轉去處理特殊事件的操作。這些引起中斷的事件稱為中斷源,它們可能是來自外設的輸入輸出請求,也可能是計算機的一些異常事故或其它內部原因。
  更具體地,我們定義CPU中斷為這樣一個過程:在特定的事件(中斷源,也稱中斷請求信號)觸發下引起CPU暫停正在運行的程序(主程序),轉而先去處理一段為特定事件而編寫的處理程序(中斷處理程序),等中斷處理程序處理完成后,再回到主程序被打斷的地方繼續運行。

2.中斷的作用
  一方面,有了中斷功能,PC系統就可以使CPU和外設同時工作,使系統可以及時地響應外部事件。而且有了中斷功能,CPU可允許多個外設同時工作。這樣就大大提高了CPU的利用率,也提高了數據輸入、輸出的速度。
  另一方面,有了中斷功能,就可以使CPU及時處理各種軟硬件故障。計算機在運行過程中,往往會出現事先預料不到的情況或出現一些故障,如電源掉電、存儲出錯,運算溢出等等。計算機可以利用中斷系統自行處理,而不必停機或報告工作人員。

3.中斷類型
  在PC機系統中,根據中斷源的不同,中斷常分為兩大類:硬件中斷和軟件中斷。
  硬件中斷也稱為外部中斷,它又可以分為兩種:
  1).可屏蔽中斷:是可以被CPU屏蔽的由中斷電路發出的中斷請求信號在CPU的INTR端引起的中斷,它常常由PC機的外設或一些接口功能產生,如鍵盤、打印機、串行口等。可屏蔽意味着這類型中斷可以在CPU要處理其它緊急操作時,被軟件屏蔽或忽略。
  2).非屏蔽中斷:是由CPU的NMI端引起的中斷,如當系統出現掉電、內存奇偶校驗錯誤等,系統都將使用非屏蔽中斷。非屏蔽是指CPU不能用軟件指令來禁止對這種中斷響應,也就是CPU必須響應由NMI端送來的中斷信號。
  軟件中斷,又稱為內部中斷,是指程序中使用INT中斷指令引起的中斷。

4.CPU響應中斷的條件 
  除了非屏蔽中斷外,其它中斷都可以用軟件來屏蔽或開放。系統只有具備如下的中斷條件,CPU才可能對中斷請求進行響應。
  1) 設置中斷請求觸發器
  2) 設置中斷屏蔽觸發器
  3) 設置中斷允許觸發器

5.CPU處理中斷過程 
  當滿足了中斷的條件后,CPU就會響應中斷,轉入中斷程序處理。具體的工作過程如下所述。
  1) 關中斷
  2) 保留斷點
  3) 保護現場
  4) 給出中斷入口,轉入相應的中斷服務程序
  5) 恢復現場
  6) 開中斷與返回

6.中斷沖突 
  雖然現在Windows操作系統從Win9X開始已經支持即插即用功能,大大簡化了用戶的操作,但是如果不能認出要安裝的新設備,那么自動分配中斷時就會產生沖突。現在新的硬件產品層出不窮,各種產品又相互兼容,功能類似,這就導致了操作系統常常不能正確檢測出新設備,中斷沖突也就不可避免了。

7.中斷控制器8259A的結構
  Intel 8259A是與8088/8086系列兼容的可編程的中斷控制器。后來的微機系統也沿用這種中斷機制及其功能,只是因為集成芯片技術的提高,不單獨以8259A芯片的形式出現,而是集成到一個叫做"南橋芯片"或"HUB芯片"的芯片里了。
  8259A包括以下幾個部分:
  1).中斷請求寄存器IRR(Interrupt Request Register):有8條外界中斷請求線IR0~IR7,每一條請求線有一個相應的觸發器來保存請求信號。
  2).中斷服務寄存器ISR(IN Service Register):保存正在服務的中斷。
  3).優先權電路:對保存在IRR中的各個中斷請求,經過判斷確定最高的優先權,並在中斷響應周期把它選通至中斷服務寄存器。
  4).中斷屏蔽寄存器IMR(Interrupt Mask Register):寄存器的每一位,可以對IRR中的相應的中斷源進行屏蔽。但對於較高優先權的輸入線實現屏蔽並不影響較低優先權的輸入。
  5).數據總線緩沖器:是8259A與系統數據總線的接口,它是8位的雙向三態緩沖器。凡是CPU對8259A編程時的控制字,都是通過它寫入8259A的,8259A狀態信息,也是通過它讀入CPU的;在中斷響應周期,8259A送至數據總線的CALL指令或中斷向量也是通過它傳送的。
  6).讀/寫控制邏輯:CPU能通過它實現對8259A的讀出(狀態信號)和寫入(初始化編程)。
  7).級連緩沖器:實現8259A芯片之間的級連,使得中斷源可由8級擴展至64級。
  8).控制邏輯部分:對芯片內部的工作進行控制,使它按編程的規定工作。

8.8259A的級連
  在一個系統中,8259A可以級連,有一個主8259A,若干個從8259A,最多可以有8個從8259A,把中斷源擴展到64個。

 

 

非 法 傳 送 種 種

1.兩個操作數的類型不一致 –-----例如源操作數是字節,而目的操作數是字;或相反

• 絕大多數雙操作數指令,除非特別說明,目的操作數與源操作數必須類型一致,否則為非法指令 MOV AL , 050AH;非法指令:050Ah為字,而AL為字節

• 寄存器有明確的字節或字類型,有寄存器參與的指令其操作數類型就是寄存器的類型

• 對於存儲器單元與立即數同時作為操作數的情況,必須顯式指明;

byte ptr 指示字節類型 , word ptr 指示字類型。

2.兩個操作數不能都是存儲器 –------傳送指令很靈活,但主存之間的直接傳送卻不允許

• 8086指令系統不允許兩個操作數都是存儲單元(除串操作指令),要實現這種傳送,可通過寄存器間接實現

mov ax , buffer1;ax←buffer1(將buffer1內容送ax)

mov buffer2 , ax;buffer2←ax;這里buffer1和buffer2是兩個字變量、;實際表示直接尋址方式

3.段寄存器的操作有一些限制 –----段寄存器屬專用寄存器,對他們的操作能力有限

• 不允許立即數傳送給段寄存器 MOV DS,100H;非法指令:立即數不能傳送段寄存器

• 不允許直接改變CS值 MOV CS,[SI] ;不允許使用的指令

• 不允許段寄存器之間的直接數據傳送 MOV DS,ES;非法指令:不允許段寄存器間傳送

MOV BL,AX(數據長度不匹配)

MOV DS,2000H(不允許給段存儲器用立即數賦值)

MOV CS,AX(禁止用MOV指令給CS賦值)

MOV [AX],[2000H](禁止直接在存儲器間傳送)

MOV [2000H],20H(數據長度不確切,應改為

MOV BYTE PTR [2000H],20H)

 

1、(1)狀態標志:CF-進位標志,ZF-零標志,SF-符號標志,PF-奇偶標志

          OF-溢出標志,AF-輔助進位標志。

  (2)控制標志:DF-方向標志,IF-中斷允許標志,TF-陷井標志。

2、8086機器代碼格式一般是:

操作碼 尋址方式 偏移量 立即數。

3、(1)源操作數為立即尋址,目的操作數為寄存器尋址。

  (2)源操作數為寄存器相對尋址,目的操作數為寄存器尋址。

  (3)源操作數為寄存器尋址,目的操作數為寄存器間接尋址。

  (4)源操作數和目的操作數均為固定尋址。

4、此題要求出物理地址,物理地址的計算公式為:

段地址(段首地址)*10H+偏移地址(有效地址)

(1)源操作數為立即尋址方式,操作數地址就在本條指令中。

(2)源操作數為直接尋址方式,其物理地址為

   DS*10H+100H=20100H

(3)源操作數為寄存器間接尋址,其物理地址為

   SS*10H+BP=15010H

(4)源操作數為基址變址尋址,其物理地址為

   DS*10H+BX+SI+VAL=201E0H

 

 

8086 有14個16位寄存器,這14個寄存器按其用途可分為(1)通用寄存器、(2)指令指針、(3)標志寄存器和(4)段寄存器等4類。
  (1)通用寄存器有8個, 又可以分成2組,一組是數據寄存器(4個),另一組是指針寄存器及變址寄存器(4個).
  數據寄存器分為:
  AH&AL=AX(accumulator):累加寄存器,常用於運算;在乘除等指令中指定用來存放操作數,另外,所有的I/O指令都使用這一寄存器與外界設備傳送數據.
  BH&BL=BX(base):基址寄存器,常用於地址索引;
  CH&CL=CX(count):計數寄存器,常用於計數;常用於保存計算值,如在移位指令,循環(loop)和串處理指令中用作隱含的計數器.
  DH&DL=DX(data):數據寄存器,常用於數據傳遞。
  他們的特點是,這4個16位的寄存器可以分為高8位: AH, BH, CH, DH.以及低八位:AL,BL,CL,DL。這2組8位寄存器可以分別尋址,並單獨使用。
  另一組是指針寄存器和變址寄存器,包括:
  SP(Stack Pointer):堆棧指針,與SS配合使用,可指向目前的堆棧位置;
  BP(Base Pointer):基址指針寄存器,可用作SS的一個相對基址位置;
  SI(Source Index):源變址寄存器可用來存放相對於DS段之源變址指針;
  DI(Destination Index):目的變址寄存器,可用來存放相對於 ES 段之目的變址指針。
  這4個16位寄存器只能按16位進行存取操作,主要用來形成操作數的地址,用於堆棧操作和變址運算中計算操作數的有效地址。
  (2) 指令指針IP(Instruction Pointer)
  指令指針IP是一個16位專用寄存器,它指向當前需要取出的指令字節,當BIU從內存中取出一個指令字節后,IP就自動加1,指向下一個指令字節。注意,IP指向的是指令地址的段內地址偏移量,又稱偏移地址(Offset Address)或有效地址(EA,Effective Address)。
  (3)標志寄存器FR(Flag Register)
  8086有一個18位的標志寄存器FR,在FR中有意義的有9位,其中6位是狀態位,3位是控制位。
  OF: 溢出標志位OF用於反映有符號數加減運算所得結果是否溢出。如果運算結果超過當前運算位數所能表示的范圍,則稱為溢出,OF的值被置為1,否則,OF的值被清為0。
  DF:方向標志DF位用來決定在串操作指令執行時有關指針寄存器發生調整的方向。 
  IF:中斷允許標志IF位用來決定CPU是否響應CPU外部的可屏蔽中斷發出的中斷請求。但不管該標志為何值,CPU都必須響應CPU外部的不可屏蔽中斷所發出的中斷請求,以及CPU內部產生的中斷請求。具體規定如下: 
  (1)、當IF=1時,CPU可以響應CPU外部的可屏蔽中斷發出的中斷請求; 
  (2)、當IF=0時,CPU不響應CPU外部的可屏蔽中斷發出的中斷請求。 
  TF:跟蹤標志TF。該標志可用於程序調試。TF標志沒有專門的指令來設置或清楚。
  (1)如果TF=1,則CPU處於單步執行指令的工作方式,此時每執行完一條指令,就顯示CPU內各個寄存器的當前值及CPU將要執行的下一條指令。
  (2)如果TF=0,則處於連續工作模式。
  SF:符號標志SF用來反映運算結果的符號位,它與運算結果的最高位相同。在微機系統中,有符號數采用補碼表示法,所以,SF也就反映運算結果的正負號。運算結果為正數時,SF的值為0,否則其值為1。 
  ZF: 零標志ZF用來反映運算結果是否為0。如果運算結果為0,則其值為1,否則其值為0。在判斷運算結果是否為0時,可使用此標志位。 
  AF:下列情況下,輔助進位標志AF的值被置為1,否則其值為0: 
  (1)、在字操作時,發生低字節向高字節進位或借位時; 
  (2)、在字節操作時,發生低4位向高4位進位或借位時。 
  PF:奇偶標志PF用於反映運算結果中“1”的個數的奇偶性。如果“1”的個數為偶數,則PF的值為1,否則其值為0。 
  CF:進位標志CF主要用來反映運算是否產生進位或借位。如果運算結果的最高位產生了一個進位或借位,那么,其值為1,否則其值為0。) 
  4)段寄存器(Segment Register)
  為了運用所有的內存空間,8086設定了四個段寄存器,專門用來保存段地址:
  CS(Code Segment):代碼段寄存器;
  DS(Data Segment):數據段寄存器;
  SS(Stack Segment):堆棧段寄存器;
  ES(Extra Segment):附加段寄存器。
  當一個程序要執行時,就要決定程序代碼、數據和堆棧各要用到內存的哪些位置,通過設定段寄存器 CS,DS,SS 來指向這些起始位置。通常是將DS固定,而根據需要修改CS。所以,程序可以在可尋址空間小於64K的情況下被寫成任意大小。 所以,程序和其數據組合起來的大小,限制在DS 所指的64K內,這就是COM文件不得大於64K的原因。8086以內存做為戰場,用寄存器做為軍事基地,以加速工作。

 

 

由於16位/32位CPU是微機CPU的兩個重要代表,所以,在此只介紹它們內部寄存器的名稱及其主要功能。

  1、 16位寄存器組

  16位CPU所含有的寄存器有

  4個數據寄存器(AX、BX、CX和DX)

  2個變址和指針寄存器(SI和DI) 2個指針寄存器(SP和BP)

  4個段寄存器(ES、CS、SS和DS)

  1個指令指針寄存器(IP) 1個標志寄存器(Flags)

  2、 32位寄存器組

  32位CPU除了包含了先前CPU的所有寄存器,並把通用寄存器、指令指針和標志寄存器從16位擴充成32位之外,還增加了2個16位的段寄存器:FS和GS。

  32位CPU所含有的寄存器有

  4個數據寄存器(EAX、EBX、ECX和EDX)

  2個變址和指針寄存器(ESI和EDI) 2個指針寄存器(ESP和EBP)

  6個段寄存器(ES、CS、SS、DS、FS和GS)

  1個指令指針寄存器(EIP) 1個標志寄存器(EFlags)

  具有一個輸入端口和兩個輸出端口。

宏與子程序的區別
宏和子程序都是為了簡化源程序的編寫,提高程序的可維護性,但是它們二者之間存在着以下本質的區別:
1、在源程序中,通過書寫宏名來引用宏,而子程序是通過CALL指令來調用;
2、匯編程序對宏通過宏擴展來加入其定義體,宏引用多少次,就相應擴展多少次,所以,引用宏不會縮短目標程序;而子程序代碼在目標程序中只出現一次,調用子程序是執行同一程序段,因此,目標程序也得到相應的簡化;
3、宏引用時,參數是通過“實參”替換“形參”的方式來實現傳遞的,參數形式靈活多樣,而子程序調用時,參數是通過寄存器、堆棧或約定存儲單元進行傳遞的;
4、宏引用語句擴展后,目標程序中就不再有宏引用語句,運行時,不會有額外的時間開銷,而子程序的調用在目標程序中仍存在,子程序的調用和返回均需要時間。
總之,當程序片段不長,速度是關鍵因素時,可采用宏來簡化源程序,但當程序片段較長,存儲空間是關鍵因素時,可采用子程序的方法來簡化源程序和目標程序。

 

DATA  SEGMENT

MSG1  DB  

MSG2  DW

DATA  ANDS

CODE  SEGMENT

ASSUME CS:CODE,DS:DATA

START:MOV  AX,  DATA

       MOV  DS,  AX

       MOV  DX  OFFSET MSG1

(    MOV  BX

MOV  AH, 4CH

INT   21H

CODE  ENDS

END    START


關於assume的作用,許多人都簡單的解釋說,這是告訴編譯器哪一個段和哪一個段寄存器相關聯。舉個簡單例子來說: 
assume cs:code, ds:data 
這是告訴編譯器cs和code關聯,ds和data關聯,后來又看到這樣的代碼 
mov ax, data 
mov ds, ax 
讓許多人一頭霧水,既然ds和data關聯了,怎么又要把data的值送到ds,這到底是怎么回事? 
這里,先不做過多的說明,我們先看看下面這個例子: 

下面的程序,把data段中的字符串拷貝到dseg段中,並且調用dos的21h中斷的9號功能來顯示 
dseg段中的字符串: 

;segtest.asm 
data segment 
    msg    db    'Hello, how are you ?', 0dh, 0ah, 24h 
data ends 

dseg segment 
    hello    db    32  dup(0) 
        db      0dh, 0ah, 24h 
dseg ends 

code segment 
    assume cs:code, ds:dseg, es:data 
start: 
    mov ax, dseg 
    mov ds, ax    ; 把dseg段的段地址送入ds 

    mov ax, data 
    mov es, ax   ; 把data段的段地址送入es 

    mov si, offset msg      ; 把源字符串的偏移送入si 
    mov di, offset hello    ; 把目標字符串的偏移送入di 
cploop: 
    mov al, msg[si]; (1)這里是一個寄存器相對尋址,那么這個物理地址是怎么形成的呢? 
    cmp al, 24h 
    jz ok 
    mov hello[di], al; (2)這里又是一個寄存器相對尋址,這個物理地址又是怎么形成的? 
    inc si 
    inc di 
    jmp short cploop 

ok: 
    mov dx, offset hello 
    mov ah, 9h 
    int 21h 

    mov ax, 4c00h 
    int 21h 
code ends 
    end start 

對於(1)和(2)中兩個地址的形成我們來分析一下: 
這兩個都是寄存器相對尋址,即有效地址都是一個寄存器加上一個16位的偏移量 
對於(1) EA = (si) + msg的偏移地址 
     物理地址就是: (段寄存器)×16+EA 
     段寄存器有四個cs, ds, es, ss, 那么編譯器怎么知道用哪一個呢? 這里就顯示出了assume的作用,是assume告訴了編譯器,data段中的標號的段地址要從es中取得,即這一句: 
es:data  告訴了編譯器在data segment和data ends之間的所有的標號都要使用es作為段寄存器來尋址,於是當編譯器看到這個msg標號的時候,它就知道了這里物理地址的形成是用(es)×16+EA 
同理,對於(2),當編譯器看到hello這個標號的時候,它就知道要取ds中的值作為段地址。如果沒有 
assume說明哪一個段和哪一個寄存器關聯,那么,編譯器就無法確定到底用哪一個段寄存器來計算物理地址。 

從這里,我們也可以看出,assume的作用僅僅是告訴編譯器,我碰到一個標號,要計算它的物理地址的時候,從哪一個段寄存器里面取出段值,至於這個段寄存器的值對不對,那它就不管了,這是程序員的事情,反正它只管根據assume里面的設定來用段寄存器,所以,對於程序員來說,不僅要用assume告訴編譯器計算物理地址的時候要從哪一個段寄存器取值,而且要在指令中明確的把對應段的段值送到設定好的段寄存器中。 
用偽指令assume告訴編譯器,data段中的標號的段地址要從es中取值,而指令 
mov ax, data 
mov es, ax 
則把data段的段地址送入es中,這樣編譯器計算msg標號的物理地址的時候,才能得到正確的段地址。 

當然,如果你不用assume指明哪一個段和哪一個寄存器相關聯,比如我把assume cs:code, ds:dseg, es:data改為 
assume cs:code這也可以,即我不把ds和dseg關聯,也不把es和data關聯,但是你必須在指令中明確的告訴編譯器使用哪一個段寄存器 
指令mov al, msg[si]必須改為 mov al, es:msg[si], 而指令mov hello[di], al也必須改為mov ds:hello[di], al,這樣編譯器才能知道使用哪一個段寄存器計算物理地址。如果編譯器無法確定標號的段地址,那么程序編譯就不會通過。 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM