目錄:
1.進制轉換
2.原碼、反碼、補碼
3.寄存器
4.存儲器的段結構
5.堆棧
6.傳送類指令
7.算術運算類指令(不含乘除)
8.位操作類指令
9.標志位操作指令
10.標識符、常量與變量
11.標號
12.運算符
13.偽指令
14.源程序中段寄存器的裝入以及DOS返回
15.分支程序設計
16.循環程序設計
17.子程序設計
18.乘除法運算
19.BCD碼校正
20.符號擴展指令
21.串操作指令
內容:
一、進制轉換
1.二進制轉為十進制:
方法:按權相加法,即將二進制每位上的數乘以權,然后相加之和即是十進制數。
例:(101.101)2=(5.625)10
2.十進制轉為二進制:
1)整數部分:
方法:除2取余法(短除法),即每次將整數部分除以2,記錄余數,而商繼續除以2,繼續記錄余數,這個步驟一直持續下去,直到商為0為止,最后讀數時候,逆序讀每一個余數。下面舉例:
例:將十進制的168轉換為二進制
得出結果 將十進制的168轉換為二進制,(10101000)2
分析:第一步,將168除以2,商84,余數為0。
第二步,將商84除以2,商42余數為0。
第三步,將商42除以2,商21余數為0。
第四步,將商21除以2,商10余數為1。
第五步,將商10除以2,商5余數為0。
第六步,將商5除以2,商2余數為1。
第七步,將商2除以2,商1余數為0。
第八步,將商1除以2,商0余數為1。
第九步,讀數,因為最后一位是經過多次除以2才得到的,因此它是最高位,讀數字從最后的余數向前讀,即10101000
2) 小數部分
方法:乘2取整法,即將小數部分乘以2,然后取整數部分,剩下的小數部分繼續乘以2,然后取整數部分,剩下的小數部分又乘以2,一直取到小數部分
為零為止。如果永遠不能為零,就同十進制數的四舍五入一樣,按照要求保留多少位小數時,就根據后面一位是0還是1,取舍,如果是零,舍掉,如果是1,向入一位。換句話說就是0舍1入。讀數要從前面的整數讀到后面的整數,下面舉例:
例1:將0.125換算為二進制
得出結果:將0.125換算為二進制(0.001)2
分析:第一步,將0.125乘以2,得0.25,則整數部分為0,小數部分為0.25;
第二步, 將小數部分0.25乘以2,得0.5,則整數部分為0,小數部分為0.5;
第三步, 將小數部分0.5乘以2,得1.0,則整數部分為1,小數部分為0.0;
第四步,讀數,從第一位讀起,讀到最后一位,即為0.001。
3.在二進制與八進制、十六進制轉化的時候,三位二進制位對應一位八進制位,四位二進制位對應一位十六進制位。
4.其他進制間的轉化可以借助十進制與二進制的轉化。
二、原碼、反碼、補碼
1.原碼即真值+符號位。反碼即原碼取反。補碼即反碼+1。
2.由負數的真值或原碼變補碼的方法:自最低位向高位逐位檢查,遇到第一個‘1’及以前(較低位)的各位‘0’保持不變,以后各高位取反。若是原碼變補碼,因最高位為符號位,不改變。
3.內存里皆以補碼表示。對一個數求補,即求負。
4.反碼算數運算若有進位則要回送給最低位,而補碼算數運算若有進位則舍棄。
三、寄存器
1、寄存器匯總
AX(AH、AL)累加器;
BX(BH、BL)基址寄存器;
CX(CH、CL)計數寄存器;
DX(DH、DL)數據寄存器;
SP 堆棧指針;
BP 基址指針;
SI 源變址寄存器;
DI 目的變址寄存器;
IP 指令指針;
FLAGS 標志寄存器;
CS 代碼段寄存器;
DS 數據段寄存器;
SS 堆棧段寄存器;
ES 附加段寄存器。
其中,通用寄存器有:AX,BX,CX,DX,SP,BP,SI,DI。
2、標志寄存器的各標志位(復位(0)、置位(1))
1)溢出位OF,置位OV,復位NV。判斷運算結果是否超出補碼范圍。溢出則置位。
2)方向位DF,置位DN,復位UP。決定串操作指令執行時指針寄存器的調整方向。DF=0時,正向處理(低位->高位),SI/DI遞增。反之,亦然。
3)中斷位IF,置位EI,復位DI。
4)符號位SF,置位NG,復位PL。與運算結果的最高位相一致。
5)零值位ZF,置位ZR,復位NZ。若運算結果為0,置位。否則,清0。
6)輔助進位位AF,置位AC,復位NA。若低4位出現進位或者借位,置位。否則,清0。
7)奇偶位PF,置位PE,復位PO。若運算結果低8位中‘1’個數為偶,則置位。否則,清0。
8)進位位CF,置位CY,復位NC。若最高位進位或者借位,則置位。在移位類指令中用來保存移出的0或1。
四、存儲器的段結構
1.邏輯段的開始地址必須是任一小節的首地址。自0地址開始,每16字節為一小節。1MB的存儲空間為65536小節。
2.邏輯段最大為1MB,最小為16B。
3.物理地址=16位段基值*16+偏移量
五、堆棧
1.在x86中,堆棧向下增長,是按字組織的,即最小數據單元為一個字。
2.當SP初始化時,它指向棧底+2字節單元,它的值就是這個堆棧的長度。
3.BP作為基址,一直不變;而SP作為棧頂指針,隨棧頂的移動而移動。
4.壓棧:PUSH。兩步:SP<=SP-2;SP<=數據。
出棧:POP。兩步:數據單元<=SP;SP<=SP+2。
PUSHF:將標志寄存器內容壓棧。
POPF:將棧頂一個字數據送入標志寄存器。
六、傳送類指令:源操作數與目的操作數類型必須一致(即同一個字節或字大小)。
1.MOV:MOV DEST,SRC 功能:DEST<=SRC。
源操作數與目的操作數不可同時為存儲單元。對FLAGS沒有影響。
2.XCHG:XCHG DEST,SRC 功能:交換DEST與SRC內容。
源操作數與目的操作數不可同時為存儲單元。對FLAGS沒有影響。
3.LAHF:LAHF 功能:將FLAGS低8位傳送至AH,即把SF,ZF,AF,PF,CF分別傳送至AH的第7,6,4,2,0位,AH其他位任意值。
對FLAGS沒有影響。
4.SAHF:SAHF 功能:將AH的內容送入FLAGS低8位。
只影響SF,ZF,AF,PF,CF位。
5.PUSHF:PUSHF 功能:將標志寄存器內容壓棧。
對FLAGS沒有影響。
6.POPF:POPF 功能:將棧頂一個字數據送入標志寄存器。
影響FLAGS所有的位。
7.LEA:LEA DEST,SRC 功能:將SRC的有效地址EA送入DEST。其中,SRC必須為一個字節或字的存儲器操作數,DEST必須為一個16位的通用寄存器。
對FLAGS沒有影響。
8.LDS/LES:LDS/LES DEST,SRC 功能:將SRC所指32位存儲單元的低16位送入DEST,而高16位送入DS(LDS指令)或ES(LES指令)。其中,DEST必須為一個16位通用寄存器,SRC必須是一個存儲器操作數,該地址單元中存放着32位地址,低16位是偏移量,高16位是段基址。
對FLAGS沒有影響。
9.XLAT (OPR):XLAT (OPR) 功能:AL<=[BX+AL],即將BX與AL相加形成EA,再將地址對應的字節存儲單元內容送入AL中。OPR可寫可不寫,沒有實際作用,只是為了增加程序可讀性而設置的,其內容為一個偏移量,和BX內容相同,存放一個表格的首地址。
對FLAGS沒有影響。
七、算術運算類指令(不含乘除):源操作數與目的操作數類型必須一致(即同一個字節或字大小)。
1.ADD:ADD DEST,SRC 功能:DEST<=DEST+SRC
源操作數與目的操作數不可同時為存儲單元。該指令會根據運算結果設置FLAGS的CF、PF、AF、ZF、SF和OF位。
2.ADC:ADC DEST,SRC 功能:DEST<=DEST+SRC+CF。帶進位的加法。
源操作數與目的操作數不可同時為存儲單元。該指令會根據運算結果設置FLAGS的CF、PF、AF、ZF、SF和OF位。
3.INC:INC DEST 功能:DEST<=DEST+1 其中,DEST可以為通用寄存器,也可以為存儲單元。
該指令會根據運算結果設置FLAGS的PF、AF、ZF、SF和OF位,但不影響CF位。
4.SUB:SUB DEST,SRC 功能:DEST<=DEST-SRC
源操作數與目的操作數不可同時為存儲單元。該指令會根據運算結果設置FLAGS的CF、PF、AF、ZF、SF和OF位。
5.SBB:SBB DEST,SRC 功能:DEST<=DEST-SRC-CF。帶借位的減法。
源操作數與目的操作數不可同時為存儲單元。該指令會根據運算結果設置FLAGS的CF、PF、AF、ZF、SF和OF位。
6.DEC:DEC DEST 功能:DEST<=DEST-1 其中,DEST可以為通用寄存器,也可以為存儲單元。
該指令會根據運算結果設置FLAGS的PF、AF、ZF、SF和OF位,但不影響CF位。
7.NEG:NEG DEST 功能:DEST<=0-DEST 求補運算,也可以說是求負運算。
若字節操作數為-128(80H)或字操作數為-32768(8000H)時,該指令執行后,操作數不變,OF置位;否則,OF復位。若操作數為0,那么結果不變,CF復位;否則,置位。
該指令會根據運算結果設置FLAGS的CF、PF、AF、ZF、SF和OF位。
8.CMP:CMP DEST,SRC 功能:與SUB基本相同,唯一不同的是目的操作數不變。
源操作數與目的操作數不可同時為存儲單元。該指令會根據運算結果設置FLAGS的CF、PF、AF、ZF、SF和OF位。
八、位操作類指令:源操作數與目的操作數類型必須一致(即同一個字節或字大小)
1.AND:AND DEST,SRC 功能:DEST<=DEST&SRC
源操作數與目的操作數不可同時為存儲單元。該指令會根據運算結果設置FLAGS的PF、ZF、SF位,CF和OF位總復位,AF位不確定。
2.TEST:TEST DEST,SRC 功能:與AND基本相同,唯一不同的是,DEST不變。常用於測試目的操作數的某一位或某幾位的狀態。
源操作數與目的操作數不可同時為存儲單元。該指令會根據運算結果設置FLAGS的PF、ZF、SF位,CF和OF位總復位,AF位不確定。
3.OR:OR DEST,SRC 功能:DEST<=DEST|SRC
源操作數與目的操作數不可同時為存儲單元。該指令會根據運算結果設置FLAGS的PF、ZF、SF位,CF和OF位總復位,AF位不確定。
4.XOR:XOR DEST,SRC 功能:DEST<=DEST^SRC
源操作數與目的操作數不可同時為存儲單元。該指令會根據運算結果設置FLAGS的PF、ZF、SF位,CF和OF位總復位,AF位不確定。
5.NOT:NOT DEST 功能:DEST<=~DEST(按位取反)
對FLAGS無影響。
6.SAL:SAL DEST,COUNT 功能:DEST<=DEST<<COUNT 算數左移指令:左移COUNT位,每移動一位,最低位補0,移出的最高位送入CF位。其中,如果COUNT=1,指令中可直接用1代替COUNT的位置;如果COUNT>1,那么必須用CL來代替COUNT的位置,移位位數由CL決定。
該指令會根據運算結果設置FLAGS的CF、PF、ZF、SF和OF位,AF位不確定。若移位位數為1次,且移位前后DEST最高位發生變化,則OF置位,否則復位。若移位位數>1,那么OF不確定。
7.SAR:SAR DEST,COUNT 功能:DEST<=DEST>>COUNT 算數右移指令:右移COUNT位,每移動一位,最高位補原有值,移出的最低位送入CF位。其中,如果COUNT=1,指令中可直接用1代替COUNT的位置;如果COUNT>1,那么必須用CL來代替COUNT的位置,移位位數由CL決定。
該指令會根據運算結果設置FLAGS的CF、PF、ZF、SF和OF位,AF位不確定。若移位位數為1次,且移位前后DEST最高位發生變化,則OF置位,否則復位。若移位位數>1,那么OF不確定。
8.SHL:SHL DEST,COUNT 功能:與SAL完全相同 邏輯左移指令
9.SHR:SHR DEST,COUNT 功能:邏輯右移指令:將DEST右移COUNT位,每移動一位,最高位補0,移出的最低位送入CF位。其中,如果COUNT=1,指令中可直接用1代替COUNT的位置;如果COUNT>1,那么必須用CL來代替COUNT的位置,移位位數由CL決定。
該指令會根據運算結果設置FLAGS的CF、PF、ZF、SF和OF位,AF位不確定。若移位位數為1次,且移位前后DEST最高位發生變化,則OF置位,否則復位。若移位位數>1,那么OF不確定。
10.ROL:ROL DEST,COUNT 功能:循環左移指令:每移動一位,把移出的最高位送入最低位和CF位。其中,如果COUNT=1,指令中可直接用1代替COUNT的位置;如果COUNT>1,那么必須用CL來代替COUNT的位置,移位位數由CL決定。
只影響FLAGS的CF和OF位。若移位位數為1次,且移位前后DEST最高位發生變化,則OF置位,否則復位。若移位位數>1,那么OF不確定。
11.ROR:ROR DEST,COUNT 功能:循環右移指令:每移動一位,把移出的最低位送入最高位和CF位。其中,如果COUNT=1,指令中可直接用1代替COUNT的位置;如果COUNT>1,那么必須用CL來代替COUNT的位置,移位位數由CL決定。
只影響FLAGS的CF和OF位。若移位位數為1次,且移位前后DEST最高位發生變化,則OF置位,否則復位。若移位位數>1,那么OF不確定。
12.RCL:RCL DEST,COUNT 功能:帶進位的循環左移指令:每移動一位,把CF位送入最低位,把移出的最高位送入CF位。其中,如果COUNT=1,指令中可直接用1代替COUNT的位置;如果COUNT>1,那么必須用CL來代替COUNT的位置,移位位數由CL決定。
只影響FLAGS的CF和OF位。若移位位數為1次,且移位前后DEST最高位發生變化,則OF置位,否則復位。若移位位數>1,那么OF不確定。
13.RCR:RCR DEST,COUNT 功能:帶進位的循環右移指令:每移動一位,把CF位送入最高位,把移出的最低位送入CF位。其中,如果COUNT=1,指令中可直接用1代替COUNT的位置;如果COUNT>1,那么必須用CL來代替COUNT的位置,移位位數由CL決定。
只影響FLAGS的CF和OF位。若移位位數為1次,且移位前后DEST最高位發生變化,則OF置位,否則復位。若移位位數>1,那么OF不確定。
九、標志位操作指令:
1.CLC:CLC 功能:CF=0
2.STC:STC 功能:CF=1
3.CMC:CMC 功能:CF=~CF
4.CLD:CLD 功能:DF=0
5.STD:STD 功能:DF=1
6.CLI:CLI 功能:IF=0
7.STI:STI 功能:IF=1
十、標識符、常量與變量:
1.標識符組成規則:(無大小寫區分)
(1)最多由31個字符組成;
(2)必須是以字母、‘?’、‘@’或‘_'開始;
(3)除第一個字符外,可以是字母、數字、‘?’、‘@’或‘_';
(4)不能是系統專用保留字。
2.常量表示:
(1)二進制常量:B(b)后綴;
(2)十進制常量:D(d)后綴,可省略;
(3)八進制常量:Q(q)或O(o)后綴;
(4)十六進制常量:H(h)后綴。對於A~F或a~f開頭的十六進制數,必須在其前加一個0,以便與標識符區分開。
(5)實數常量:通常以十進制表示,由整數、小數和指數三部分組成。eg:-1.23E-4;9.0E+4。實數必須由偽指令DD、DQ、DT定義,實數不能出現在表達式中。另外,實數也可以用十六進制數直接說明其二進制數編碼形式,但是這個十六進制數必須以0~9開頭,不帶符號,並在用R作后綴。
(6)字符串常量:用單引號括起來的一個或多個字符。有大小寫區分。
3.變量定義:DB(字節變量)、DW(字變量)、DD(雙字變量)、DQ(四字變量)、DT(五字變量)。
4.變量屬性:
(1)SEG:所在段的段基值;
(2)OFFSET:距離段基址的字節數(偏移量);
(3)TYPE:所占存儲單元的字節數。
5.變量預置:
(1)數值表達式:eg:VA DW 1234H,0ABCDH (依次以小尾方式存儲,前一個單元12H放高字節,34H放低字節,后一單元同樣)
(2)字符串表達式:每一個字符占一個字節單元。
1)使用DB:字符串不超過255個字符,大尾方式存放。eg:VA DB 'ABCDEF' (從’A'至'F'按地址遞增排列)
2)使用DW:最多為兩個字符組成的字符串分配存儲單元,小尾方式存放。eg:VA DW 'AB','CD','EF' (地址遞增排序為:'BADCFE')
3)使用DD:最多為兩個字符組成的字符串分配存儲單元,小尾方式存放,且第2個字單元存放0000H。eg:VA DD 'AB','CD' (地址遞增排序為:'B''A''00''00''D''C''00''00')
(3)?表達式:預置隨機值。eg:VA DB ?,?
(4)地址表達式:若該地址表達式為一變量名或者標號名,那么DW定義則是用其偏移量預置;DD定義則是用其段基值和偏移量預置,且段基值存高字單元,偏移量存低字單元。eg:VB DD VA (VB的高字單元存放VA的段基值,低字單元存VA的偏移量)
(5)帶DUP的表達式:格式:變量名 偽指令 n DUP(表達式) 功能:定義重復數據。
eg:VA DW 10H DUP(4) (即分配了10H個字單元,都每個字單元預置4) VB DB 10H DUP('ABCD') (分配了10H個字符串’ABCD‘,共10H*4=40H個字節)
DUP可以嵌套使用。
eg:VA DB 10H DUP(4 DUP(2),3,4)等價於 VA DB 10H DUP(2,2,2,2,3,4)
(6)混合使用:eg:VA DB 2 DUP(1),2 DUP(2,'B'),'123',1,2
十一、標號:
1.屬性:
(1)SEG:所在段的段基值;
(2)OFFSET:距離段基址的字節數(偏移量);
(3)類型屬性Distance:NEAR、FAR。
2.類型屬性設置:
(1)缺省默認NEAR。
(2)LABEL偽指令方式:建立新的標號並賦予指定類型屬性。
eg:J1 LABEL FAR
J2: MOV AX,20H
兩個標號J1和J2指向同一個地方,但類型屬性不同。
十二、運算符:
1.算術運算符:+、-、*、/、MOD、[]。
2.移位運算符:SHR(右移),SHL(左移) eg:MOV AX,11011011B SHL 3等價於MOV AX,1101011000B
3.邏輯運算符:NOT、AND、OR、XOR eg:MOV AX,NOT 0F0H
4.關系運算符:EQ(相等為真A=B)、NE(不相等為真A!=B)、LT(A<B)、LE(A<=B)、GT(A>B)、GE(A>=B)。表達式都是常數或者同段的偏移量。如果是常數,按照無符號數比較;如果是變量,比較其偏移量。比較結果以真(全1)或假(全0)給出。 eg:MOV AX,0FH EQ 1111B等價於MOV AX,0FFFFH
5.數值返回運算符:
(1)SEG:返回變量或者標號的段基值。 eg:MOV AX,SEG VA
(2)OFFSET:返回變量或標號的偏移量。eg:MOV AX,OFFSET VA
(3)TYPE:返回變量或標號的類型屬性的數字形式:變量(BYTE(1)、WORD(2)、DWORD(4))、標號(NEAR(-1)、FAR(-2)) eg:MOV AX,TYPE VA
(4)LENGTH:僅用於變量之前,返回數組變量的元素個數。如果變量包含DUP,那么返回其重復值n;否則,返回1。 eg:MOV AX,LENGTH VA
(5)SIZE:僅用於變量之前,返回數組變量所占的總字節數,即等價於LENGTH與TYPE的乘積。 eg:MOV AX,SIZE VA
6.屬性修改運算符:
(1)PTR:格式:類型 PTR 地址表達式 其中,地址表達式是指要修改或指定類型屬性的標號、變量或用做地址指針的寄存器。不過,此修改僅在PTR語句里生效,臨時修改而已。 eg:MOV AX,WORD PTR DATA_BYTE[10] MOV WORD PTR [SI],30H
(2)HIGH和LOW:只放在一個常數或在能確定其段基值或偏移量的地址表達式前面,用來分離運算對象的高字節和低字節。
eg:CONST EQU 0ABCDH
MOV AH,HIGH CONST
eg2:MOV BH,HIGH(SEG DA1)
十三、偽指令:
1.EQU:等值偽指令:格式:符號名 EQU 表達式 其中,表達式可以是常數、數值表達式、字符串、地址表達式、標號、變量、指令助記符或關鍵字等。
eg:CONT EQU 5 ADR EQU ES:10H[BX] VA EQU AX VA EQU ADD。
不能重復定義,除非解除原先定義。
PURGE:用來解除EQU的定義。eg:PURGE CONT,ADR 注意:不能用PURGE解除被PUBLIC說明的符號的定義
2.=:格式:符號名=表達式。eg:CONT=5
與EQU的區別:(1)=允許重復定義;(2)=后的表達式不能是指令助記符或關鍵字。
3.DB(字節變量)、DW(字變量)、DD(雙字變量)、DQ(四字變量)、DT(五字變量)
4.LABEL:與PTR功能相同,並且作用不受限制。
(1)改變標號屬性:見前面的(十一.2.(2))。
(2)改變變量屬性:
eg:VA LABEL BYTE
VB DW 20H DUP(0)
VA與VB段基值、偏移量都相同,但類型不相同。
5.段定義偽指令
格式:段名 SEGMENT [定位類型][組合類型][類別名]
......
段名 ENDS
6.ASSUME:段尋址偽指令,指定邏輯段與段寄存器之間的關系。eg:ASSUME CS:CODE,DS:DATA
注意:(1)該指令不產生機器碼。
(2)若不指定,程序中使用變量名或地址表達式時要加上段前綴。eg:MOV AX,ES:VA
(3)該指令也可以取消或修改指定關系。
eg:ASSUME ES:NOTHING ;刪除對ES的關聯 ASSUME NOTHING ;刪除所有關聯
7.PROC/ENDP:過程定義偽指令。
格式:過程名 PROC [NEAR/FAR]
......
RET
......
過程名 ENDP
8.ORG/$:定位偽指令和當前位置計數器。
eg:ORG 30H;該語句之后的指令或數據以當前值30H作為起始偏移量。 eg:ORG $+20H ;$即當前位置計數器
注意:ORG后的表達式以65536為模進行計算,即兩個字節;而$與變量做減法時值為一個字節,如:VA2 EQU $-VA 此時VA2占據一個字節的內存。
9.TITLE:標題偽指令。格式:TITLE 標題名
10.END:程序結束偽指令。格式:END 起始地址 功能:一方面表示什么時候結束程序,一方面指定程序裝入內存時根據起始地址對CS和IP裝入對應的段基值和偏移量。
11.PUBLIC/EXTRN:前者用來定義全局符號,后者用來標明當前模塊中要訪問的本模塊之外的符號。
十四、源程序中段寄存器的裝入以及DOS返回:
1.DS和ES的裝入:
DS:MOV AX,DATA MOV DS,AX
ES:MOV AX,DATA2 MOV ES,AX
2.SS的裝入:
(1)系統自動裝入:在定義堆棧邏輯段時,指定其組合類型為STACK,並在ASSUME中關聯。eg:STACK1 SEGMENT STACK ........
(2)手動法:

1 STACK1 SEGMENT 2 DW 20H DUP(?) 3 TOP LABEL WORD 4 STACK1 ENDS 5 6 CODE SEGMENT 7 ...... 8 MOV AX,STACK1 9 MOV SS,AX 10 MOV SP,OFFSET TOP 11 .......
3.CS的裝入:
一般方法:程序結束偽指令END直接搞定,裝入CS和IP。格式:END 起始地址
4.DOS返回:
(1)用4CH系統功能調用實現返回:即在程序結束時加上:MOV AH,4CH INT 21H
(2)用程序段前綴實現返回:三步:1)把程序編制成一個過程,設置為FAR。2)把PSP起始地址壓棧。3)程序結束時RET。

1 CODE SEGMENT 2 PROC1 PROC FAR 3 ASSUME CS:CODE,... 4 START: PUSH DS ;保存PSP首地址,RET返回時將其裝入CS 5 MOV AX,0 6 PUSH AX ;RET返回時把00H作為偏移量裝入IP 7 ... 8 RET 9 PROC1 ENDP 10 CODE ENDS 11 END START
十五、分支程序設計:
1.無條件轉移指令JMP:不影響FLAGS。
(1)段內轉移:只需要修改IP值。
1)直接尋址:JMP TARGET (TARGET為標號) 指令編碼2~3字節。
2)間接尋址:JMP REG或者JMP ADDR (REG為寄存器,ADDR為字存儲單元,存儲着目標地址) 指令編程2~4字節
eg:JMP CX; JMP WORD PTR [BX]; JMP VA;
(2)段間轉移:需要修改CS和IP值。
1)直接尋址:JMP TARGET 指令編碼5字節。
2)間接尋址:JMP ADDR (ADDR為雙字存儲單元,存儲目標地址) 指令編碼2~4字節 eg:JMP DWORD PTR VA[BX]
2.條件轉移指令:格式:JXX TARGET (TARGET為標號) 執行的操作:IP<=TARGET的偏移量 指令編碼都是2字節。
該系列指令只能在段內直接尋址,並且轉移范圍在從下一條指令算起的-128~127個字節的地址范圍內。且不影響FLAGS。
(1)簡單條件轉移指令:
JC CF=1 有進位/借位
JNC CF=0 無進位/借位
JE/JZ ZF=1 相等/等於0
JNE/JNZ ZF=0 不相等/不等於0
JS SF=1 為負數
JNS SF=0 為正數
JO OF=1 有溢出
JNO OF=0 無溢出
JP/JPE PF=1 有偶數個1
JNP/JPO PF=0 有奇數個1
(2)無符號數條件轉移指令:假設此指令前進行無符號數A、B的比較,指令的操作為A-B
JA/JNBE CF=0&&ZF=0 A>B
JAE/JNB CF=0||ZF=1 A>=B
JB/JNAE CF=1&&ZF=0 A<B
JBE/JNA CF=1||ZF=1 A<=B
(3)有符號數條件轉移指令:假設此指令前進行有符號數A、B的比較,指令的操作為A-B
JG/JNLE SF=OF&&ZF=0 A>B
JGE/JNL SF=OF||ZF=1 A>=B
JL/JNGE SF!=OF&&ZF=0 A<B
JLE/JNG SF!=OF||ZF=1 A<=B
3.對於多路分支,可以使用跳轉表法。
(1)跳轉表由入口地址構成:

1 DATA SEGMENT 2 ATABLE DW V1,V2 3 DW V3,V4 4 N DB 3 5 Y DW 0F786H 6 DATA ENDS 7 STACK1 SEGMENT STACK 8 DW 20H DUP(?) 9 STACK1 ENDS 10 CODE SEGMENT 11 ASSUME CS:CODE,DS:DATA,SS:STACK1 12 START: MOV AX,DATA 13 MOV DS,AX 14 MOV BX,OFFSET ATABLE 15 XOR AH,AH 16 MOV AL,N 17 DEC AL 18 SHL AL,1 19 ADD BX,AX 20 JMP WORD PTR [BX] 21 V1: 22 ADD Y,100 23 JMP DONE 24 V2: 25 ADD Y,99 26 JMP DONE 27 V3: 28 ADD Y,98 29 JMP DONE 30 V4: 31 ADD Y,97 32 JMP DONE 33 DONE: MOV AH,4CH 34 INT 21H 35 CODE ENDS 36 END START 37
(2)跳轉表由JMP指令構成:

1 DATA SEGMENT 2 N DB 3 3 Y DW 0F786H 4 DATA ENDS 5 STACK1 SEGMENT STACK 6 DW 20H DUP(?) 7 STACK1 ENDS 8 CODE SEGMENT 9 ASSUME CS:CODE,DS:DATA,SS:STACK1 10 START: MOV AX,DATA 11 MOV DS,AX 12 MOV CX,OFFSET ATABLE 13 XOR BH,BH 14 MOV BL,N 15 DEC BL 16 MOV AL,BL 17 SHL BL,1 18 ADD BX,CX 19 JMP BX 20 ATABLE: 21 JMP V1 22 JMP V2 23 JMP V3 24 JMP V4 25 V1: 26 ADD Y,100 27 JMP DONE 28 V2: 29 ADD Y,99 30 JMP DONE 31 V3: 32 ADD Y,98 33 JMP DONE 34 V4: 35 ADD Y,97 36 JMP DONE 37 DONE: MOV AH,4CH 38 INT 21H 39 CODE ENDS 40 END START 41
十六、循環程序設計:
循環控制指令:使用CX作為計數器,采用段內直接尋址,操作數為標號,不影響FLAGS。格式都是:LOOP TARGET。指令編碼2字節。並且轉移范圍在從下一條指令算起的-128~127個字節的地址范圍內。
LOOP: 首先CX<=CX-1。如果CX!=0,則IP<=TARGET的偏移量;否則,順序執行。
LOOPZ/LOOPE:首先CX<=CX-1。如果CX!=0&&ZF=1,則IP<=TARGET的偏移量;否則,順序執行。
LOOPNZ/LOOPNE:首先CX<=CX-1。如果CX!=0&&ZF!=1,則IP<=TARGET的偏移量;否則,順序執行。
JCXZ: 測試CX==0,但不修改其值。如果CX=0,則IP<=TARGET的偏移量;否則,順序執行。
十七、子程序設計:
1.子程序定義格式:
過程名 PROC [NEAR/FAR]
......
RET
......
過程名 ENDP
2.段內調用:
(1)直接調用:CALL PROC_NAME(過程名) 指令操作:將IP壓棧,IP<=子程序入口偏移量 指令編碼3字節
(2)間接調用:CALL REG或者CALL W_ADDR (操作數為通用寄存器或者變量、標號) 指令操作:將IP壓棧,IP<=REG/W_ADDR. 指令編碼2~4字節
3.段間調用:
(1)直接調用:CALL PROC_NAME(FAR屬性) 指令操作:依次將CS、IP壓棧,CS<=子程序段基值,IP<=子程序偏移量。 指令編碼5字節。
(2)間接調用:CALL DW_ADDR (操作數為變量或標號) 指令操作:依次將CS、IP壓棧,IP<=第一個字存儲單元內容,CS<=第二個字存儲單元內容。 指令編碼2~4字節。
4.返回指令RET:
(1)段內返回:RET 或 RET n(n為偶數)。 指令操作:對IP出棧。如果帶有n,則SP<=SP+n。 不帶操作數時編碼為C3,單字節;帶操作數時3字節。
(2)段間返回:RET 或 RET n(n為偶數)。 指令操作:先對IP出棧,再對CS出棧。如果帶有n,則SP<=SP+n。 不帶操作數時編碼為CB,單字節;帶操作數時3字節。
其中,RET n的作用是將call指令前壓棧的參數數據占據的空間釋放。
5.子程序與主程序之間的參數傳遞可以通過寄存器、堆棧或者地址表實現。這里不表。
十八、乘除法運算:
1.無符號數乘法MUL:MUL OPRD 只影響FLAGS中的CF和OF。若乘積的高半部分不為0,則CF=OF=1;否則,CF=OF=0。其他標志位不確定。
字節乘法:AX=AL*OPRD 乘積放入AX中。
字乘法: DX:AX=AX*OPRD 乘積的高字放入DX,低字放入AX。
2.帶符號數乘法IMUL:IMUL OPRD 只影響FLAGS中的CF和OF。如果乘積的高半部分不是低半部分的符號擴展,則CF=OF=1;否則,CF=OF=0。其他標志位不確定。
字節乘法:AX=AL*OPRD 乘積放入AX中。
字乘法: DX:AX=AX*OPRD 乘積的高字放入DX,低字放入AX。
3.無符號數除法DIV:DIV OPRD 不影響FLAGS。
字節除法:被除數AX 除數OPRD 商AL 余數AH
字除法: 被除數DX:AX除數OPRD 商AX 余數DX
如果除數為0或者商AL>0FFH或者AL>0FFFFH,轉入0型中斷。
4.帶符號數除法IDIV:IDIV OPRD 不影響FLAGS。
字節除法:被除數AX 除數OPRD 商AL 余數AH
字除法: 被除數DX:AX除數OPRD 商AX 余數DX
如果除數為0或者商AL>7FH或者AL>7FFFH,轉入0型中斷。
十九、BCD碼校正:需要注意的是,除法校正指令寫在除法運算指令之前,而其他指令都是寫在相應運算指令之后。
1.x86采用先用二進制運算指令進行算術運算,再用BCD碼校正。
2.組合型BCD碼:一個字節表示兩個十進制數;
非組合型BCD碼:一個字節只表示一位十進制數。
3.非組合型加法校正指令AAA:若AL中低4位的數>9,或AF=1,則AL<=AL+6,AH<=AH+1,且AL中高4位清0,AF、CF置一。
4.組合型加法校正指令DAA:若AL中低4位>9或者AF=1,則AL<=AL+6,並置AF=1。
若AL中高4位>9或者CF=1,則AL<=AL+60H,並置CF=1。
5.非組合型減法校正指令AAS:若AL中低4位>9或者AF=1,則依次執行:AL<=AL-6,AH<=AH-1,AL高4位清0,CF=AF=1。
6.組合型減法校正指令DAS:若AL中低4位>9或者AF=1,則AL<=AL-6,並置AF=1。
若AL中高4位>9或者CF=1,則AL<=AL-60H,並置CF=1。
7.非組合型乘法校正指令AAM:對在AL中的積(由兩個組合的BCD碼相乘的結果)進行校正,產生兩個非組合的BCD碼。
指令的操作:把AL的值除以10,商放在AH中,余數放在AL中。
該指令影響FLAGS的SF、ZF和PF。
8.非組合型除法校正指令AAD:把存放在AH和AL中的兩位非組合BCD碼調整為一個二進制數,存放在AL中。
指令的操作:AL<=AH*10+AL,AH=0。
該指令影響FLAGS的SF、ZF和PF。
二十、符號擴展指令:
1.字節擴展為字 CBW:CBW 功能:當AL最高位為1,則AH變為1111B;當AL最高位為0,則AH變為0000B。
不影響FLAGS。
2.字擴展為雙字 CWD:CWD 功能:當AX最高位為1,則DX變為FFFFH;當AX最高位為0,則DX變為0000H。
不影響FLAGS。
二十一、串操作指令:
1.串操作指令的源操作數地址由DS:[SI]提供,目的串操作數地址由ES:[DI]提供。每條串操作指令每次僅對串中的一個字或字節單元進行操作,且同時自動修改SI或者DI。若DF=0,則SI/DI遞增1個字節或字;若DF=1,則SI/DI遞減1個字節或字。還有重復前綴指令,重復次數由CX決定。
2.1.取串指令LODS:LODS 源串
LODSB ;取源串一個字節 等價於:MOV AL,[SI] INC/DEC SI
LODSW ;取源串一個字 等價於:MOV AX,[SI] ADD/SUB SI,2
不影響FLAGS。
2.2.存串指令STOS:STOS 目的串
STOSB ;送入目的串一個字節 等價於:MOV [DI],AL INC/DEC DI
STOSW ;送入目的串一個字 等價於:MOV [DI],AX ADD/SUB DI,2
不影響FLAGS。
2.3.串傳送指令MOVS:MOVS 目的串,源串
MOVSB ;字節傳送 等價於:把BYTE PTR [SI]傳給[DI],並修改SI和DI。
MOVSB ;字傳送 等價於:把WORD PTR [SI]傳給[DI],並修改SI和DI。
不影響FLAGS。
2.4.串比較指令CMPS:CMPS 源串,目的串
CMPSB ;字節比較
CMPSW ;字比較
影響FLAGS。
需要注意的是:串比較指令在比較時是源操作數減目的操作數,而一般比較指令是目的操作數減源操作數。
2.5.串搜索指令SCAS:SCAS 目的串
SCASB
SCASW
影響FLAGS。
查找方法:在目的串中找AX或AL指定的內容。用AX或AL內容減去目的串中一個字或字節,相減結果反映在FLAGS中。每查找一次,按照DF修改DI。
3.重復前綴指令REP:前面的指令都是操作一個字節或字,若操作一個字符串,則可用REP指令。每執行一次串操作指令,CX減1,直到CX=0為止。
REP:重復執行條件是:CX!=0 用於LODS、STOS、MOVS對應指令之前。
REPE/REPZ:重復執行條件是:CX!=0&&ZF=1。 用於CMPS、SCAS對應指令之前。
REPNE/REPNZ:重復執行條件是:CX!=0&&ZF=0。 用於CMPS、SCAS對應指令之前。
實驗部分:可以參考http://wenku.baidu.com/view/8d9f9aef0975f46527d3e10b.html。