學(xué)習(xí)匯編語言,最關(guān)鍵的就在于匯編指令集的掌握以及計算機工作方式的理解,以下是80X86匯編過程中經(jīng)常用到的一些匯編指令。
從功能分類上來說,一共可分為
一、數(shù)據(jù)傳送指令:MOV、XCHG、LEA、LDS、LES、PUSH、POP、PUSHF、POPF、CBW、CWD、CWDE。
二、算術(shù)指令:ADD、ADC、INC、SUB、SBB、DEC、CMP、MUL、DIV、DAA、DAS、AAA、AAS。
三、邏輯指令:AND、OR、XOR、NOT、TEST、SHL、SAL、SHR、SAR、RCL、RCR、ROL、ROR。
四、控制轉(zhuǎn)移指令:JMP、Jcc、JCXZ、LOOP、LOOPZ、LOOPNZ、LOOPNE、CALL、RET、INT。
五、串操作指令:MOVS、LODS、STOS、CMPS、SCAS。
六、標(biāo)志處理指令:CLC、STC、CLD、STD。
七、32位CPU新增指令(后續(xù)補充并完善)
除上述的一些指令外,還有許多32位80X86CPU新增指令,這些指令有時會簡化程序設(shè)計,不過由于我也是剛剛學(xué)習(xí)匯編,這些都是從書上看到的,所以很多還不是十分了解,我寫這些的目的僅僅是想讓自己能更好的去記住這些指令的作用和用法,同事也希望和我一樣剛?cè)腴T的朋友能夠多了解一些,并沒有其他目的,所有的示例也并沒有經(jīng)過實際的代碼測試,所以希望各位朋友,不管你喜歡不喜歡,反對不反對,請文明發(fā)言,謝謝!
------------------------------------------------數(shù)據(jù)傳送指令開始-------------------------------------------------------
1、MOV(傳送)
指令寫法:MOVtarget,source
功能描述:將源操作數(shù)source的值復(fù)制到target中去,source值不變
注意事項:1)target不能是CS(代碼段寄存器),我的理解是代碼段不可寫,只可讀,所以相應(yīng)這地方也不能對CS執(zhí)行復(fù)制操作。2)target和source不能同時為內(nèi)存數(shù)、段寄存器(CSDSESSSFSGS)3)不能將立即數(shù)傳送給段寄存器4)target和source必須類型匹配,比如,要么都是字節(jié),要么都是字或者都是雙字等。4)由于立即數(shù)沒有明確的類型,所以將立即數(shù)傳送到target時,系統(tǒng)會自動將立即數(shù)零擴展到與target數(shù)的位數(shù)相同,再進行傳送。有時,需要用BYTEPTR 、WORDPTR、DWORDPTR明確指出立即數(shù)的位數(shù)
寫法示例:MOVdl,01H;MOVeax,[bp]; eax=ss:[bp] 雙字傳送。
2、XCHG(交換)
指令寫法:XCHGobject1,object2
功能描述:交換object1與object2的值
注意事項:1)不能直接交換兩個內(nèi)存數(shù)的值2)類型必須匹配3)兩個操作數(shù)任何一個都不能是段寄存器【看來段寄存器的寫入的限制非常的嚴(yán)格,MOV指令也不能對段寄存器進行寫入】,4)必須是通用寄存器(ax、bx、cx、dx、si、di)或內(nèi)存數(shù)
寫法示例:XCHGax,[bx][si]; XCHGax,bx;
3、LEA(裝入有效地址)
指令寫法:LEZreg16,mem
功能描述:將有效地址MEM的值裝入到16位的通用寄存器中。
寫法示例:假定bx=5678H,EAX=1,EDX=2
Leasi,2[bx];si=567AH
Leadi,2[eax][edx];di=5
注意,這里裝入的是有效地址,并不是實際的內(nèi)存中的數(shù)值,如果要想取內(nèi)存中該地址對應(yīng)的數(shù)值,還需要加上段地址才行,而段地址有可能保存在DS中,也有可能保存在SS或者CS中哦:>不知道我的理解可正確。。。。
4、LDSLESLGSLSS(注意,與LEA不同的是,這里是裝入的值,而不是有效地址)
這幾個指令,名稱不同,作用差不多。
寫法:LDSreg16,mem32
功能描述:reg16等于mem32的低字,而DS對應(yīng)于mem32的高字(當(dāng)為LES時,這里就是ES對應(yīng)于mem32的高字)
用來給一個段寄存器和一個16位通用寄存器同時復(fù)制。
注意事項:第一個操作數(shù)必須是16位通用寄存器
在接著往下說之前,先熟悉下堆棧的概念。堆棧,位于內(nèi)存的堆棧段中,是內(nèi)存的一部分,具有“先進后出”的特點,堆棧只有一個入口,即當(dāng)前棧頂,當(dāng)堆棧為空時,棧頂和棧底指向同一內(nèi)存地址,在WINDOWS中,可以把堆棧理解成一個倒著的啤酒瓶,上面的地址大,下面的地址小,當(dāng)從瓶口往啤酒瓶塞啤酒時(進棧),棧頂就會往瓶口下移動,也就是往低地址方向移動,同理,出棧時,正好相反,把啤酒給倒出來,棧頂向高地址方向移動。這就是所謂的堆棧,哼哼,很Easy吧。
在匯編語言中,堆棧操作的最小單位是字,也就是說,只能以字或雙字為單位,同時,SS:SP指向棧頂(SS為堆棧段寄存器,SP為堆棧指針,二者一相加,就構(gòu)成了堆棧棧頂?shù)膬?nèi)存地址)。
5、PUSH(進棧)
寫法:PUSH reg16(32)/seg/mem16(32)/imm
功能描述:將通用寄存器/段寄存器/內(nèi)存數(shù)/立即數(shù)的值壓入棧中,即:
SP=SP-2SS:[SP]=16位數(shù)值(當(dāng)將32位數(shù)值壓入棧中時,SP=SP-4,SS:[SP]=32為數(shù)值)
6、POP(出棧)
寫法:POP reg16(32)/seg/mem16(32)【不能出棧到CS中】
功能描述:將堆??诘?6(32)位數(shù)據(jù)推出到通用寄存器/段寄存器/內(nèi)存中,即:
寄存器/段寄存器/內(nèi)存= SS:[SP] SP=SP+2(當(dāng)將32位數(shù)值出棧時,SP=SP+4)(注意,不能出棧給立即數(shù)哦,常量不可變嘛)
7、PUSHA、PUSHAD、POPA、POPAD
作用:將所有16/32位通用寄存器進棧/出棧
如:PUSHA ;將AX、CX、DX、BX、原SP、BP、SI、DI依次進棧。POPA出棧順序正好相反,但要注意的是,彈出到SP的值被丟棄,SP通過增加16位來恢復(fù)(當(dāng)然嘛,不然棧頂?shù)刂肪捅恍薷牧耍蜁鱿⒉粚R的情況,就有可能亂套了)
POPAD PUSHAD一樣,只不過是32位的罷了。
8、PUSHF、PUSHFD、POPF、POPFD
功能描述:標(biāo)志寄存器FLAGS(EFLAGS)進棧或出棧
如:PUSHF ;FLAGS進棧POPF;棧頂字出棧到FLAGS
總結(jié)下,POP 和PUSH通??梢杂脕斫粨Q兩個寄存器的值,也可以用來保護寄存器的值,如下:
交換ax與cx的值:push ax;push cx;pop ax;popcx;
保護寄存器:push ax;push cx;….中間有很多執(zhí)行的代碼…pop cx;pop ax;
9、LAHFSAHF(標(biāo)志寄存器傳送指令)
寫法:lahf;
作用:AH=FLAGS的低8位
寫法:sahf;
作用:FLAGS的低8位=AH
10、符號擴展和零擴展指令
CBW;AL符號擴展為AX
CWD;AX符號擴展為32位數(shù)DX:AX
CWDE;AX符號擴展為EAX;
CDQ:EAX符號擴展為64位數(shù)EDX:EAX
MOVSX(符號擴展指令的一般形式)
寫法:MOVSXreg1632,reg8reg16mem8mem16
作用:用來將8位符號擴展到16位,或者16位符號擴展到32位
MOVZX(零擴展指令)
寫法:MOVZXreg1632,reg8reg16mem8mem16
零擴展,就是高位補0進行擴展。通常用在將數(shù)據(jù)復(fù)制到一個不同的寄存器中,如AL零擴展為EBX。相同寄存器的零擴展,可以使用MOV高位, 0來實現(xiàn)。
11、BSWAP(字節(jié)交換)
寫法:bswap reg32
作用:將reg32的第0與第3個字節(jié),第1與第2個字節(jié)進行交換。
示例:設(shè)EAX=12345678h
執(zhí)行bswap eax;后,eax=78563412H
12、XLAT(換碼)
寫法:XLAT;
作用:AL=DS:[bx+AL]
將DS:BX所指內(nèi)存中的由AL指定位移處的一個字節(jié)賦值給AL。(貌似這是一個方便偷懶的指令哦。。),原來它的主要用途是查表。注意可以給它提供操作數(shù),用來指定使用哪個段地址,如:
XLAT ES:table;使用ES來作為段地址,table不起作用。
XLAT table ;使用table所在段對應(yīng)的段寄存器作為段地址。
---------------------------------------------- --數(shù)據(jù)傳送指令結(jié)束-----------------------------------------------------------------------------------------算術(shù)指令開始-----------------------------------------------
13、ADD(加法)
寫法:ADD reg/mem reg/mem/imm
作用:將后面的操作數(shù)加到前面的操作數(shù)中
注意:兩個操作數(shù)必須類型匹配,并且不能同時是內(nèi)存操作數(shù)
ADC (帶進位加法)
寫法:ADC reg/mem, reg/mem/imm ;
作用:dest=dest+src+cf
當(dāng)CF=0時 ADD與ADC的作用是相同的。
示例:實現(xiàn)64位數(shù)EDX:EAX與ECX:EBX的加法:
Add EAX,EBX;
ADC EDX,ECX;
14、INC(自加一)
寫法:INC reg/mem;
作用:dest=dest+1;
15、XADD(交換加)
寫法:XADD reg/mem, reg
作用:先將兩個數(shù)交換,然將二者之和送給第一個數(shù)
16、SUB(減法)
寫法:SUB reg/mem, reg/mem/imm;
作用:dest=dest-src;
SBB(帶借位減法)
寫法:SBB reg/mem, reg/mem/imm
作用:dest=dest-src-cf;
注意:兩個操作數(shù)必須類型匹配,且不能同時是內(nèi)存數(shù)
17、DEC(自減1)
寫法:DEC reg/mem;
作用:dest=dest-1;
18、CMP(比較)
寫法:CMP reg/mem, reg/mem/imm
作用:dest-src
注意:這里并不將結(jié)果存入dest中,而僅僅是執(zhí)行相減的運算,達到依據(jù)運算結(jié)果去影響EFLAG標(biāo)志位的效果
19、NEG(求補)
寫法:NEG reg/mem
作用:求補就是求相反數(shù),即:dest=0-dest;
20、CMPXCHG(比較交換)
寫法:CMPXCHG reg/mem, reg;
作用:AL/AX/EAX-oprd1,如果等于0,則oprd1=oprd2,否則,AL/AX/EAX=oprd1;
即:比較AL/AX/EAX與第一個操作數(shù),如果相等,則置ZF=1,并復(fù)制第二個操作數(shù)給第一個操作數(shù);否則,置ZF=0,并復(fù)制第一個操作數(shù)給AL/AX/EAX。
說明:CMPXCHG主要為實現(xiàn)原子操作提供支持
CMPXCHG8B(8字節(jié)比較交換指令)
寫法:CMPXCHG8B MEM64;
功能:將EDX:EAX中的64位數(shù)與內(nèi)存的64位數(shù)進行比較,如果相等,則置ZF=1,并存儲ECX:EBX到mem64指定的內(nèi)存地址;否則,置ZF=0,并設(shè)置EDX:EAX為mem64的8字節(jié)內(nèi)容
21、MUL(無符號乘法)
寫法:MUL reg/mem;
作用:當(dāng)操作數(shù)為8位時,AX=AL*src;
當(dāng)操作數(shù)為16位時,DX:AX=AX*src;
當(dāng)操作數(shù)為32位時,EDX:EAX=EAX*src;
22、IMUL(帶符號位乘法)
寫法:IMUL reg/mem;(作用同上)
IMUL reg16,reg16/mem16,imm16;
IMUL reg32,reg32/mem32,imm32;
IMUL reg16,imm16/reg16/imm16;
IMUL reg32,reg32/mem32/imm32;
注意:沒有兩個操作數(shù)均為8位的多操作數(shù)乘法。
對于同一個二進制數(shù),采用MUL和IMUL執(zhí)行的結(jié)果可能不同,設(shè)AL=0FF,BL=1,分別執(zhí)行下面的指令,會得到不同的結(jié)果:
Mul bl; AX=0FFH(255);
Imul bl; AX=0FFFFH(-1)(高一半為低一半的擴展)
23、DIV(無符號除法 )/IDIV(帶符號數(shù)除法)
寫法:DIV reg/mem;/IDIC reg/mem
作用:如果操作數(shù)是8位,AX%SRC,結(jié)果商在AL、余數(shù)在AH中;
如果操作數(shù)是16位,DX:AX%SRC,結(jié)果商在AX,余數(shù)在DX中;
如果操作數(shù)是32位,EDX:EAX%SRC,結(jié)果商在EAX,余數(shù)在EDX中;
注意:不能直接實現(xiàn)8位數(shù)除8位數(shù)、16位數(shù)除16位數(shù)、32除32,若需要這樣,則必須先把除數(shù)符號擴展或零擴展到16、32、64位,然后用除法指令。
對于IDIV,余數(shù)和被除數(shù)符號相同,如:-5 IDIV 2 = 商-2,余數(shù):-1;
在下列情況下,會使CPU產(chǎn)生中斷:一:除數(shù)為0;二:由于商太大,導(dǎo)致EAXAX或AL不能容納,從而產(chǎn)生了溢出。
-----------------BCD碼調(diào)整指令(十進制調(diào)整指令)待補充------------------------------------------------
24、關(guān)于BCD碼:BCD碼就是一種十進制數(shù)的二進制編碼表示,分為壓縮BCD碼和非壓縮BCD碼,壓縮BCD碼用4個二進制位表示一個十進制位,即用0000B~1001B表示十進制0~9,如01100100 0010 1001B表示6429
用8位二進制來表示一個十進制叫非壓縮BCD碼,其中,低四位與壓縮BCD碼相同,高四位無意義。
壓縮BCD碼調(diào)整指令包括DAA(加法的壓縮BCD碼調(diào)整)和DAS(減法的壓縮BCD碼調(diào)整)
寫法:
DAA;
作用:調(diào)整AL中的和為壓縮BCD碼。
功能:使用DAA指令時,通常先執(zhí)行ADD/ADC指令,將兩個壓縮BCD碼相加,結(jié)果存放在AL中,然后使用該指令將AL調(diào)整為壓縮BCD碼格式。
DAA的調(diào)整算法:
IF(AL低4位>9 或 AF=1)
THEN
AL=AL+6;
AF=1;
ENDIF
IF( AL高4位>9或CF=1)
THEN
AL=AL+60H;
CF=1;
ENDIF
說明:CF反映壓縮BCD碼相加的進位。
DAS;
作用:調(diào)整AL中的差為壓縮BCD碼。
功能:使用DAS指令時,通常先執(zhí)行SUB/SBB指令,將兩個壓縮BCD碼相減,結(jié)果存放在AL中,然后使用該指令將AL調(diào)整為壓縮BCD碼格式。
DAS的調(diào)整算法:
IF(AL低4位>9 或 AF=1)
THEN
AL=AL-6;
AF=1;
ENDIF
IF( AL高4位>9或CF=1)
THEN
AL=AL-60H;
CF=1;
ENDIF
說明:CF反映壓縮BCD碼相減的借位。
特別注意,如果使用DAA或DAS指令,則參加加法或減法運算的操作數(shù)應(yīng)該是壓縮BCD碼,如果將任意兩個二進制數(shù)相加或相減,然后調(diào)整,則得不到正確的結(jié)果。
關(guān)鍵是調(diào)整的規(guī)則,其中AF標(biāo)志位就是專門為BCD碼調(diào)整設(shè)計的,當(dāng)?shù)退奈挥邢蚋咚奈贿M位或借位時,值為1。而CF就是最高位有進位或者借位時,為1.
非壓縮BCD碼調(diào)整指令,包括AAA,AAS,AAM,AAD。
寫法:AAA ;
作用:調(diào)整AL中的和為非壓縮BCD碼;調(diào)整后,AL高4位等于0,AH=AH+產(chǎn)生的CF
功能:使用AAA指令時,通常先執(zhí)行ADD/ADC指令,以AL為目的操作數(shù),將兩個非壓縮BCD碼(與高位無關(guān))相加,然后使用AAA將AL調(diào)整為非壓縮BCD碼格式,且高4位等于0,同時,將調(diào)整產(chǎn)生的進位加到AH中。
AAA調(diào)整算法:
IF(AL低4位>9 或者 AF=1)
THEN
AL=AL+6;
AH=AH+1;
AF=1;
CF=1;
ELSE
AF=0;CF=0;
ENDIF
AL=AL AND OFH;;AL高4位清0
寫法:AAS ;
作用:調(diào)整AL中的差為非壓縮BCD碼;調(diào)整后,AL高4位等于0,AH=AH-產(chǎn)生的CF
功能:使用AAS指令時,通常先執(zhí)行SUB/SBB指令,以AL為目的操作數(shù),將兩個非壓縮BCD碼(與高位無關(guān))相減,然后使用AAS將AL調(diào)整為非壓縮BCD碼格式,且高4位等于0,同時,將調(diào)整產(chǎn)生的借位從AH中減去。
AAA調(diào)整算法:
IF(AL低4位>9 或者 AF=1)
THEN
AL=AL-6;
AH=AH-1;
AF=1;
CF=1;
ELSE
AF=0;CF=0;
ENDIF
AL=AL AND OFH;;AL高4位清0
寫法:AAM;
作用:AH=AX DIV 10, AL=AX MOD 10;
功能:使用AAM時,通常先執(zhí)行MUL/IMUL指令,將兩個一字節(jié)非壓縮BCD碼(高四位必須為0)相乘,結(jié)果存入AX.然后使用AAM指令將AX(AH=0)調(diào)整為兩字節(jié)壓縮BUC碼格式。
寫法:AAD;
作用:AL=AH*10+AL,AH=0;
功能:使用AAD時,通常先執(zhí)行該指令,將AX中的兩字節(jié)非壓縮BCD碼(AH與AL的高4位必須為0)調(diào)整為相應(yīng)的二進制表示,然后使用DIV/IDIV指令,除以一個一字節(jié)的非壓縮BCD碼(高四位必須為0),可得到非壓縮BCD碼的除法結(jié)果。
特別注意,參加非壓縮BCD碼乘法或除法的操作數(shù)高4位必須為0。
-----------------------------算術(shù)指令結(jié)束-----------------------------------------------------------------------------
-----------------------------------------位操作指令開始-----------------------------------------------------
25、ANDORXORNOTTEST
寫法:
AND reg/mem,reg/mem/imm;
OR reg/mem,reg/mem/imm;
XOR reg/mem,reg/mem/imm;
NOT reg/mem;
TEST reg/mem,reg/mem/imm;
作用:ANDTESTORXOR,兩個操作數(shù)必須類型匹配,而且不能同時是內(nèi)存操作數(shù)。
XOR通常用來將寄存器清0,如 XOR AX,AX;
TEST與AND的關(guān)系類似于CMP與SUB。TEST的典型用法是檢查某位是否為1,如:
TEST DX,109H;
若 DX的第0,3,8位至少有一位為1,則 ZF=0,否則ZF=1;
26、移位指令
SHL(邏輯左移)
寫法:SHL REGmem,1CL ;
作用:將dest的各個二進制位向左移動1(CL)位,并將DEST的最高位移出到CF,最低位移入0。
SAL(算術(shù)左移)
寫法:SAL REGmem,1CL ;
作用:將dest的各個二進制位向左移動1(CL)位,并將DEST的最高位移出到CF,最低位移入0(同SHL)。
SHR(邏輯右移)
寫法:SHR REGmem,1CL ;
作用:將dest的各個二進制位向左移動1(CL)位,并將DEST的最低位移出到CF,最高位移入0。
SAR(算術(shù)右移)
寫法:SAR REGmem,1CL ;
作用:將dest的各個二進制位向左移動1(CL)位,并將DEST的最低位移出到CF,最高位不變。
SHLD(雙精度左移)
寫法:SHLD REG16/REG32/MEM16/MEM32, REG16/REG32,IMM8/CL;(類型須匹配)
作用:將OPRD1的各二進制左移,并將oprd1的最高位移到CF,oprd2的最高位移到oprd1的最低位,但是,oprd2的值不變。
SHRD(雙精度右移)
寫法與作用與雙精度左移類似。注意移動方向為右移。
以上位移指令對標(biāo)志位的影響:
若移位后符號位發(fā)生了變化,則OF=1,否則OF=0;CF為最后移入位;按一般規(guī)則影響ZF與SF。然而,若移位次數(shù)為0,則不影響標(biāo)志位;若移位次數(shù)大于1,則OF無定義。
27、循環(huán)移位指令
ROL(循環(huán)左移)
寫法:ROL REGMEM, 1CL;或 ROLREG/MEM,IMM8;(類型可不匹配)
作用:將DEST的各二進制位向左移動,并將最高位移出到CF,并同時移入最低位。
ROR(循環(huán)右移)
寫法:ROR REGMEM, 1CL;或 RORREG/MEM,IMM8;(類型可不匹配)
作用:將DEST的各二進制位向右移動,并將最低位移出到CF,并同時移入最高位。
RCL(帶進位循環(huán)左移)
寫法:RCL REGMEM, 1CL;或 RCLREG/MEM,IMM8;(類型可不匹配)
作用:將DEST的各二進制位向左移動,并將最高位移出到CF,原CF移入最低位。
RCR(帶進位循環(huán)右移)
寫法:RCR REGMEM, 1CL;或 RCRREG/MEM,IMM8;(類型可不匹配)
作用:將DEST的各二進制位向右移動,并將最低位移出到CF,原CF移入最高位。
28、位測試指令
BT(位測試)
寫法:BT REG16/MEM16,REG16/IMM8;或BTREG32/MEM32,REG32/IMM8;
作用:CF=DEST的第index位,dest不變。
BTS(位測試并置位)
寫法:BTS REG16/MEM16,REG16/IMM8;或BTSREG32/MEM32,REG32/IMM8;
作用:CF=DEST的第index位,dest的第index位=1;
BTR(位測試并復(fù)位)
寫法:BTR REG16/MEM16,REG16/IMM8;或BTRREG32/MEM32,REG32/IMM8;
作用:CF=DEST的第index位,dest的第index位=0;
BTC(位測試并復(fù)位)
寫法:BTC REG16/MEM16,REG16/IMM8;或BTCREG32/MEM32,REG32/IMM8;
作用:CF=DEST的第index位,dest的第index位取反;
說明:若dest為寄存器,則以index除以16(dest為reg16)或32(dest為reg32)的余數(shù)作為測試位。當(dāng)然,index最好不要超出操作數(shù)的位數(shù)。
若dest為內(nèi)存操作數(shù),則無論其類型為字或雙字,測試位為相對于起始地址的位移,例如,設(shè)BX=50,X為字類型的變量,則執(zhí)行指令BTX,BX;后,CF=X+6單元的第2位,因為50%8=6余2.
BTS、BTC、BTR指令可用于并發(fā)程序設(shè)計。
29、位掃描指令
BSF(前向位掃描)
寫法:BSF reg16/reg32, reg16/reg32/mem16/mem32;(類型須匹配)
作用:dest=src中值為1的最低位編號(從低位向高位搜索)
BSR(后向位掃描)
寫法:BSR reg16/reg32, reg16/reg32/mem16/mem32;(類型須匹配)
作用:dest=src中值為1的最高位編號(從高位向低位搜索)
說明:BSF和BSR搜索SRC操作數(shù)中首次出現(xiàn)1的位置,BSF從低位向高位搜索,BSR反之。若找到一個1,則置ZF=0,并存儲位編號到DEST操作數(shù)中。若SRC=0,即沒有1出現(xiàn),則置ZF=1,且dest的值不確定。
比如,有如下二進制數(shù)0111 1111 1010 0100
執(zhí)行bsf后,位編號為2,執(zhí)行bsr后,位編號為14.
30、條件置位指令
通用寫法:SETcc reg8/mem8
作用:若條件cc成立,則dest=1,否則,dest=0;
SETcc有很多種命令形式,這里的cc只是一個描述符,具體的參見下面的三個表,其中,E(Equal)表示相等,G(Greatet)表示帶符號大于,L(Less)表示帶符號小于,A(Above)表示無符號大于,B(Below)表示無符號小于。
表一:測試單個標(biāo)志位的SETcc指令:
SETcc指令 | 描述 | 置1條件 |
SETC,SETB,SETNAE | 有進位時置1 | CF=1 |
SETNC,SETNB,SETAE | 無進位時置1 | CF=0 |
SETZ,SETE | 為0(相等)時置1 | ZF=1 |
SETNA,SETNE | 非0(不等)時置1 | ZF=0 |
SETS | 為負(fù)時置1 | SF=1 |
SETNS | 為正時置1 | SF=0 |
SET0 | 溢出時置1 | OF=1 |
SETNO | 不溢出時置1 | OF=0 |
SETP,SETPE | ‘1’的個數(shù)為偶數(shù)時置1 | PF=1 |
SETNP,SETPO | ‘1’的個數(shù)為奇數(shù)時置1 | PF=0 |
表二:用于帶符號數(shù)比較的SETcc指令,這些指令常用在CMP指令之后,以判斷帶符號數(shù)的大小:
SETcc指令 | 描述 | 置1條件 |
SETG,SETNLE | 大于(不小于等于)時置1 | SF=OF且ZF=0 |
SETGE,SETNL | 大于等于(不小于)時置1 | SF=OF |
SETL,SETNGE | 小于(不大于等于)時置1 | SF≠OF |
SETLE,SETNG | 小于等于(不大于)時置1 | SF≠OF或ZF=1 |
表三:用于無符號數(shù)比較的SETcc指令,常用在CMP指令之后,用來判斷無符號數(shù)的大?。?/p>
SETcc指令 | 描述 | 置1條件 |
SETA,SETNBE | 大于(不小于等于)時置1 | CF=0且ZF=0 |
SETAE,SETNB,SETNC | 大于等于(不小于)時置1 | CF=0 |
SETB,SETNAE,SETC | 小于(不大于等于)時置1 | CF=1 |
SETBE,SETNA | 小于等于(不大于)時置1 | CF=1或ZF=1 |
-----------------------------------------位操作指令結(jié)束----------------------------------------------------
----------------------------------------------------
---------------------------控制轉(zhuǎn)移指令開始--------------------------------------------------
31、JMP(無條件轉(zhuǎn)移指令)
執(zhí)行代碼的跳轉(zhuǎn),分為兩種,一:段內(nèi)轉(zhuǎn)移,即要跳過去的代碼地址和當(dāng)前地址在同一段,這時只要修改IP(專用寄存器--指令指針)即可;二:段間轉(zhuǎn)移:即要跳過去的代碼地址和當(dāng)前代碼地址不在同一段內(nèi),需要同時修改CS和IP的值。
寫法:
1、JMPlabel;若label與該指令位于同一代碼段內(nèi),IP=label的偏移地址,否則CS:IP=label的分段地址,簡單的說,就是跳到label的地址去。
2、JMPreg16/mem16;段內(nèi)轉(zhuǎn)移,偏移地址=reg16/[mem16]
3、JMPmem32;段間間接轉(zhuǎn)移,段地址CS=mem32高字,偏移地址IP=mem32低字。
說明:當(dāng)操作數(shù)是內(nèi)存操作數(shù)時,若內(nèi)存操作數(shù)是雙字類型,則產(chǎn)生段間轉(zhuǎn)移,若內(nèi)存操作數(shù)是字類型,則產(chǎn)生段內(nèi)間接轉(zhuǎn)移。當(dāng)不能確定類型時,編譯器將報錯。
32、Jcc(條件轉(zhuǎn)移指令)
寫法:Jcc label;
作用:若條件成立,則IP=label的偏移地址,否則,CPU將忽略該條件轉(zhuǎn)移,繼續(xù)執(zhí)行下一條指令。
條件轉(zhuǎn)移有以下幾種形式:
表一:測試單個標(biāo)志位的Jcc指令:
Jcc指令 | 描述 | 轉(zhuǎn)移條件 |
JC,JB,JNAE | 有進位時轉(zhuǎn)移 | CF=1 |
JNC,JNB,JAE | 無進位時轉(zhuǎn)移 | CF=0 |
JZ,JE | 為零(相等)時轉(zhuǎn)移 | ZF=1 |
JNZ,JNE | 非零(不等)時轉(zhuǎn)移 | ZF=0 |
JS | 為負(fù)時轉(zhuǎn)移 ![]() | SF=1 |
JNS | 為正時轉(zhuǎn)移 | SF=0 |
JO | 溢出時轉(zhuǎn)移 | OF=1 |
JON | 不溢出時轉(zhuǎn)移 | OF=0 |
JP,JPE | ‘1’的個數(shù)為偶數(shù)時轉(zhuǎn)移 | PF=1 |
JNP,JPO | ‘1’的個數(shù)為奇數(shù)時轉(zhuǎn)移 | PF=0 |
表二:用于帶符號數(shù)比較的Jcc指令(常用在CMP指令之后,以判斷帶符號數(shù)的大?。?/p>
Jcc指令 | 描述 | 轉(zhuǎn)移條件 |
JG,JNLE | 大于(不小于等于)時轉(zhuǎn)移 | SF=OF且ZF=0 |
JGE,JNL | 大于等于(不小于)時轉(zhuǎn)移 | SF=OF |
JL,LNGE | 小于(不大于等于)時轉(zhuǎn)移 | SF<>OF |
JLE,LNG | 小于等于(不大于)時轉(zhuǎn)移 | SF<>OF或ZF=1 |
表三:用于無符號數(shù)比較的Jcc指令(常用在CNO指令之后,以判斷無符號數(shù)的大?。?/p>
Jcc指令 | 描述 | 轉(zhuǎn)移條件 |
JA,JNBE | 大于(不小于等于)時轉(zhuǎn)移 | CF=0且ZF=0 |
JAE,JNB,JNC | 大于等于(不小于)時轉(zhuǎn)移 | CF=0 |
JB,LNAE,JC | 小于(不大于等于)時轉(zhuǎn)移 | CF=1 |
JBE,LNA | 小于等于(不大于)時轉(zhuǎn)移 | ZF=1或CF=1 |
33、JCXZ/JECXZ(Jump if CX/ECX is zero)
寫法:JCXZ label;(若CX=0,則轉(zhuǎn)移到label)
JECXZ label;(若ECX=0,則轉(zhuǎn)移到label)
說明:label相對位移量必須在-126~127之間
34、循環(huán)指令
LOOP label;
作用:CX=CX-1;若CX<>0,則轉(zhuǎn)移到label;
LOOPZ/LOOPE label;
作用:CX=CX-1;若CX<>0且 ZF=1,則轉(zhuǎn)移到label;
LOOPNZ/LOOPNE label;
作用:CX=CX-1;若CX<>0且ZF=0,則轉(zhuǎn)移到label;
說明:label相對位移量必須在-128~127之間
35、過程調(diào)用和返回指令
CALL(過程調(diào)用)
寫法:CALL label;
作用:若label與該指令在同一代碼段,則為段內(nèi)直接調(diào)用,IP進棧,IP=label的偏移地址,如果是不在同一代碼段,則為段間間接調(diào)用,CS:IP進棧,CS:IP=label的分段地址
寫法:CALL reg16/mem16;
作用:段內(nèi)間接調(diào)用,IP進棧,IP=reg16/【mem16】
寫法:CALL mem32;
作用:段間間接調(diào)用,CS:IP進棧,CS等于mem32高字,ip等于mem32低字。
該指令與JMP指令的區(qū)別就是保存了CS:IP的值,這樣在調(diào)用指令結(jié)束后,可以返回回來而已。
RET(過程返回)
寫法:RET; 近返回或遠(yuǎn)返回
RETN; 近返回;
RETF; 遠(yuǎn)返回
RET imm16; 近返回或遠(yuǎn)返回,并調(diào)整堆棧,SP=SP+imm16;
RETN imm16;近返回,并調(diào)整堆棧,SP=SP+imm16;
RETF imm16;遠(yuǎn)返回,并調(diào)整堆棧,SP=SP+imm16;
作用:RET/RETN/RETF:返回地址出棧,從而使調(diào)用返回,其中,遠(yuǎn)返回是POP一個雙字到CS:IP,而近返回是POP一個字到IP
RET/RETN/RETFimm16:在返回后,CPU立即將imm16加到堆棧指針SP。這種機制用來在返回前將參數(shù)從棧中移除。
說明:CALL 與 RET必須配合使用,并且確保返回時棧頂正好是返回地址,不然就會出錯。
36、IN T(中斷指令)
寫法:INT n;(n為中斷號,取值為0~255)
通常,程序內(nèi)部的跳轉(zhuǎn),用JMP或CALL,并且JMP和CALL得參數(shù)是要跳轉(zhuǎn)的過程的入口指令地址,而INT則是調(diào)用系統(tǒng)提供的中斷服務(wù)程序,并且參數(shù)是中斷號,然后由CPU根據(jù)中斷號去計算中斷服務(wù)程序的入口地址,MSDOS使用中斷號21H作為系統(tǒng)調(diào)用,一般INT中斷的步驟如下:
(1)由AH給出中斷號
(2)根據(jù)相應(yīng)功能的要求,設(shè)置入口參數(shù)
(3)INT 21H
(4)分析和使用出口參數(shù)
比如如下代碼實現(xiàn)程序的退出并返回DOS:
Mov ah,4ch;-----給出中斷號
Int 21h; -----開始中斷
說明:除了直接以AL或AX返回出口參數(shù)外,INT21H還是用AL或AX作為返回碼,對于功能號0~2eh,由AL返回0(表示成功)或1(表示失?。黄溆喙δ芴杽t由CF返回0或者1,并由AX返回錯誤碼。
---------------------------控制轉(zhuǎn)移指令結(jié)束--------------------------------------------------
-----------------------------標(biāo)志處理指令開始-----------------------------------------------------------
37、標(biāo)志處理指令
CLC ; CF=0
STC ; CF=1
CMC ; CF=NOT CF
CLD ; DF=0
STD ; DF=1
CLI ; IF=0(應(yīng)慎用)
STI ; IF=1
-----------------------------標(biāo)志處理指令結(jié)束-----------------------------------------------------------
---------------------------串操作指令開始--------------------------------------------------
到這為止,所涉及的指令都是處理一個操作數(shù),如果要處理連續(xù)內(nèi)存單元的一批數(shù)據(jù),通常需借助于循環(huán)。而串操作指令就可以用來處理內(nèi)存中的數(shù)據(jù)串,并在助記符后面加上B、W、D分別表示操作類型為字節(jié)、字或雙字
38、MOVS(串傳送)
寫法:
MOVSB/MOVSW/MOVSD
功能:
ES:[DI]=DS:[SI]
If(DF=0)
Then
SI=SI+size;
DI=DI+size;
Else
SI=SI-size;
DI=DI-size;
Endif
其中,size等于1(B)、2(W)、4(D).
作用:將DS:SI所指源串的一個字節(jié)/字/雙字復(fù)制到ES:DI所指的內(nèi)存單元,然后,若DF=0,則SI和DI增加1、2、4,否則減少1、2、4.
現(xiàn)在有點明白為什么SI為源變址寄存器,而DI為目標(biāo)變址寄存器了,而DS為數(shù)據(jù)段寄存器,ES為附加段寄存器了。
39、LODS(串載入)
寫法:LODSBLODSWLODSD
功能:
AL/AX/EAX=DS:[SI];
IF (DF=0) THEN
SI=SI+size;
ELSE
SI=SI-size;
Endif
作用:將DS:SI所指源串的值復(fù)制到AL/AX/EAX中,然后,根據(jù)DF使SI增加或減小1、2、4
40、STOS(串存儲)
寫法:
STOSBSTOSWSTOSD
功能:
ES:[DI]=AL/AX/EAX;
IF (DF=0) THEN
DI=DI+size;
ELSE
DI=DI-size;
ENDIF
作用:將AL/AX/EAX中的值復(fù)制到ES:[DI]所指的內(nèi)存單元中去,并根據(jù)DF標(biāo)志位的值調(diào)整DI
41、CMPS(串比較)
寫法:CMPSB/CMPSW/CMPSD
功能:
DS:[SI]-ES:[DI];
IF (DF=0) THEN
SI=SI+size;DI=DI+size;
ELSE
SI=SI-size;DI=DI-size;
ENDIF
作用:將DS:SI所指內(nèi)存值與ES:DI所指內(nèi)存值進行比較,并根據(jù)比較結(jié)果設(shè)置標(biāo)志位,然后,對SI和DI做相應(yīng)的調(diào)整。
42、SCAS(串掃描)
寫法:SCASB/SCASW/SCASD
功能:
AL/AX/EAX-ES:[DI];
IF (CF=0) THEN
DI=DI+size;
ELSE
DI=DI-size;
ENDIF
作用:將AL/AX/EAX與ES:DI所指內(nèi)存值進行比較,根據(jù)比較結(jié)果設(shè)置標(biāo)志位,然后根據(jù)DF調(diào)整相應(yīng)的DI的值。
說明:以上串操作的共性:
DS:SI指向源串,ES:DI指向目的串
SI和DI自動增加或減少1、2、4,關(guān)鍵看DF及操作類型是BWD
43、重復(fù)前綴
重復(fù)前綴用來和以上幾個串操作指令混合使用
REP(重復(fù))
功能:當(dāng)CX<>0時,重復(fù)執(zhí)行后面的串指令,每執(zhí)行一次,CX自動-1,該指令只能用在MOVSLODSSTOS之前
REPZ/REPE(為零/等于時重復(fù))
功能:當(dāng)CX<>0且ZF=1時,重復(fù)執(zhí)行后面的指令,每執(zhí)行一次,CX自動-1,該指令只能用在CMPSACAS之前。
REPNZ/REPNE(非零/不等于時重復(fù))
功能:CX<>0且ZF=0時,重復(fù)執(zhí)行后面的指令,每執(zhí)行一次,CX自動-1,該指令只能用在CMPSACAS之前。
說明:REPNE SCAS(B/W/D)適用于在多字節(jié)、字、雙字?jǐn)?shù)據(jù)結(jié)構(gòu)中搜索特定值。
---------------------------串操作指令結(jié)束--------------------------------------------------
---------------------------CPU控制指令開始--------------------------------------------------
44、NOP(無操作)
寫法:NOP;
作用:該指令不做任何事情,只占用1個字節(jié),耗費一個指令執(zhí)行周期。
45、HIT(暫停)
寫法:HIT;
作用:HIT使CPU進入暫停狀態(tài),這時CPU不執(zhí)行任何操作,直到系統(tǒng)復(fù)位或發(fā)生外部中斷為止,中斷使CPU繼續(xù)執(zhí)行后面的指令(貌似和屏保或待機的功能類似)
46、LOCK(封鎖前綴)
功能:LOCK指令用于多處理器系統(tǒng),作為某些指令的前綴,可以使CPU通過鎖住總線等方式,抱著指令作為原子性操作,即:指令執(zhí)行過程不會被打斷操作。
該指令用于以下指令的前綴時,以保證原子性的對內(nèi)存的“讀-修改-寫”操作:
1) 加法:ADDADCINCXADD
2) 減法:SUBSBBDECNEG
3) 交換:XCHGCMPXCHGCMPXCHG8B
4) 邏輯:ANDNOTORXOR
5) 位測試:BTSBTCBTR
說明:其他類型指令不能加LOCK前綴,另外,XCHG總是原子性操作,無論前面有沒有加LOCK前綴。LOCK前綴典型用于BTS指令,以實現(xiàn)多處理器環(huán)境中程序的并發(fā)執(zhí)行,如:
LOCK BTS [EBX],AX
LOCK ADD [SI],AL
---------------------------CPU控制指令結(jié)束--------------------------------------------------
到這里為止,一些基本的匯編指令都已經(jīng)學(xué)習(xí)完了,但是還得好好的去應(yīng)用,不然還真的記不住這些指令的功能。
總結(jié)一下,一般情況下,通用寄存器可以較隨便使用,段寄存器和指針寄存器用來指示位置,一般不能隨便更改,另外一個就是標(biāo)志寄存器的各個標(biāo)志位的意義也非常的重要,很多指令都是根據(jù)標(biāo)志位來執(zhí)行操作的。
接下來準(zhǔn)備學(xué)習(xí)匯編的編程格式,然后就可以寫一些簡單的程序并自己進行調(diào)試了 ,哈哈哈哈哈。偶非常的期待。
愛華網(wǎng)




