? ? ? ? 計(jì)算機(jī)通過執(zhí)行指令序列來使機(jī)器得以工作,所以對(duì)于每一系列的計(jì)算機(jī)都有指定的一組指令集供計(jì)算機(jī)使用,這組指令集就叫做計(jì)算機(jī)的指令系統(tǒng);指令可分為操作碼和操作數(shù)兩部分,計(jì)算機(jī)執(zhí)行指令時(shí)將根據(jù)對(duì)應(yīng)的二進(jìn)制代碼識(shí)別操作碼并加以執(zhí)行操作碼對(duì)應(yīng)的操作;
? ? ? ? 操作數(shù)部分比較復(fù)雜,每一條指令可根據(jù)操作數(shù)的個(gè)數(shù)分為一地址指令、二地址指令和三地址指令,其中三地址指令中有兩個(gè)操作數(shù)是源操作數(shù)加以運(yùn)算后的結(jié)果存放在第三個(gè)操作數(shù)對(duì)應(yīng)的地址單元中;二地址指令是將兩個(gè)操作數(shù)運(yùn)算過后的結(jié)果存放在第一個(gè)操作數(shù)對(duì)應(yīng)的地址單元里,所以這種操作將會(huì)使一位操作數(shù)損失,若以后還需用到該操作數(shù)應(yīng)加以提前保存副本;尋找操作數(shù)的方式相對(duì)的復(fù)雜一些,以下將做重點(diǎn)介紹。
? ? ? ? 另外匯編語(yǔ)言是一種符號(hào)語(yǔ)言,用助記符表示操作碼,用符號(hào)或者符號(hào)地址表示操作數(shù),且每一條都與機(jī)器指令一一對(duì)應(yīng);這篇文章將從80X86的尋址方式、程序占有的空間和執(zhí)行時(shí)間和80X86的指令系統(tǒng)三個(gè)方面進(jìn)行說明;(以80X86講起)
一:80X86的尋址方式
? ? ? ? 有兩個(gè)方面:與數(shù)據(jù)有關(guān)的尋址方式和與轉(zhuǎn)移地址有關(guān)的尋址方式。數(shù)據(jù)尋址方式中將以MOV ? ? D,S為例,表示把源操作數(shù)S傳送到目的操作數(shù)D中;
數(shù)據(jù)尋址方式:
1、立即尋址方式
? ? ? 操作數(shù)直接存放在指令中,作為指令的一部分存放在代碼段中,并且緊跟在操作碼之后;這種方式常常用來表示常數(shù),對(duì)寄存器進(jìn)行賦值,源操作數(shù)的長(zhǎng)度應(yīng)該和目的操作數(shù)的長(zhǎng)度一致;如:
MOV ? ? ?AX,3064H
2、寄存器尋址方式
? ? ? ? 操作數(shù)在寄存器中,不需要訪問存儲(chǔ)器,所以有較高的運(yùn)算速度;如:
MOV ? ? AX,BX
若執(zhí)行前(AX)=3064H,(BX)=1234H,執(zhí)行后(AX)=(BX)=1234H
3、直接尋址方式
? ? ? 這種方式操作數(shù)的有效地址只有位移量一種成分;如:
MOV ? ? AX,[2000H]
如果(DS)=3000好,執(zhí)行如圖:
另:用符號(hào)地址代替數(shù)值地址
MOV ? ? AX,VALUE和MOV ? ? AX,[VALUE]是等效的
4、寄存器間接尋址方式
? ? ? ? 操作數(shù)的有效地址只包含基址寄存器或者變趾寄存器內(nèi)容一種成分;另外,16位尋址時(shí)除BP寄存器默認(rèn)段寄存器為SS外,其它的默認(rèn)寄存器為DS;
如:MOV ? ? AX,[BX]
若(DS)=2000H,(BX)=1000H,則:物理地址=20000+1000=21000H,結(jié)果為(AX)=50A0H;執(zhí)行如下
5、寄存器相對(duì)尋址方式
? ? ? ? 操作數(shù)的有效地址為基址寄存器或變址寄存器的內(nèi)容與指令中指定的位移量?jī)煞N成分構(gòu)成,即兩種成分相加即為有效地址;
如:MOV ? ? AX,COUNT[SI]
也可以表示為MOV ? ? AX,[count+si](不區(qū)分大小寫);若:(ds)=3000h,(si)=2000h,count=3000h,物理地址=30000+2000+3000=35000H,執(zhí)行結(jié)果(ax)=1234h;執(zhí)行情況如下:
6、基址變址尋址方式
? ? ? 操作數(shù)的有效地址有兩種成分構(gòu)成,即變址寄存器內(nèi)容和基址寄存器內(nèi)容之和;
如:mov ? ? ax,[bx][di]或者寫為mov ? ? ax,[bx+di];若(ds)=2100h,(bx)=0158h,di=10A5h;物理地址=21000+0158+10A5=221FDH;執(zhí)行結(jié)果(ax)=1234H;如下:
7、相對(duì)基址變址尋址方式
操作數(shù)的有效地址是一個(gè)基址寄存器與一個(gè)變址寄存器的內(nèi)容和指令中指定的位移量之和,故有三種成分構(gòu)成;
如:mov ? ? ax,array[bx][si];若(ds)=3000h,(bx)=2000h,(si)=1000h,mask=0250h;物理地址=16d*3000+2000+1000+0250=33250h;執(zhí)行如下:
與轉(zhuǎn)移地址有關(guān)的尋址方式:
1、段內(nèi)直接尋址
? ? ? ? 轉(zhuǎn)向的有效地址為當(dāng)前IP內(nèi)容與指令中指定的8位或16位位移量之和;當(dāng)用于條件轉(zhuǎn)移時(shí),位移量只允許8位;當(dāng)用于無(wú)條件轉(zhuǎn)移時(shí),位移量為8位時(shí)表示段內(nèi)短轉(zhuǎn)移,此時(shí)須在位移量之前加上short字符,如jmp ? ? short quest;無(wú)條件轉(zhuǎn)移位移量為16位時(shí),稱為段內(nèi)近轉(zhuǎn)移,須在位移量前加操作符near ptr,如:jmp ? ? near ptr quest;其中quest為位移量符號(hào);
2、段內(nèi)間接尋址
? ? ? ? 這種轉(zhuǎn)移轉(zhuǎn)向的有效地址是寄存器或者存儲(chǔ)單元里的內(nèi)容,也就是將寄存器或者存儲(chǔ)單元里的內(nèi)容取代以前IP寄存器里的內(nèi)容;這種段內(nèi)轉(zhuǎn)移指令不能作為條件轉(zhuǎn)移指令使用;如:
jmp ? ? bx
jmp ? ? word ptr[bp+table]
注意:這里的轉(zhuǎn)向的有效地址是指根據(jù)尋址方式得到的存儲(chǔ)單元或者寄存器里的內(nèi)容;
3、段間直接尋址
這種轉(zhuǎn)移方式除了將指令中指定的偏移地址取代IP寄存器里的內(nèi)容外,還需要將指令中指定的內(nèi)容所在的段地址取代cs段里內(nèi)容,此時(shí)用far ptr操作符表示;如:
jmp ? ? far ptr nextroutint
4、段間間接轉(zhuǎn)移
? ? ? ? 用存儲(chǔ)器里兩個(gè)連續(xù)的字來取代cs和ip的內(nèi)容,此時(shí)存儲(chǔ)器里的內(nèi)容可以用除立即數(shù)以外的任意一種數(shù)據(jù)尋址方式獲得;若用此方式須在指令中加以dword ptr字符,如:
jmp ? ? dword ptr[inters+bx]
二、程序占有的空間和執(zhí)行時(shí)間
? ? ? ?對(duì)于一條指令來說,若為16位則一條指令的長(zhǎng)度可達(dá)到1至7個(gè)字節(jié),而對(duì)于不同的尋址方式使用操作數(shù)也需要時(shí)間這就在空間和時(shí)間上有了限制,所以編制程序時(shí)應(yīng)考慮這兩個(gè)因素使程序更加的精煉;
三、80X86的指令系統(tǒng)
? ? ? ? 此系列的指令系統(tǒng)可以分別為以下六組:數(shù)據(jù)傳送指令、串處理指令、算術(shù)指令、控制轉(zhuǎn)移指令、邏輯指令和處理機(jī)控制指令,此處不對(duì)處理機(jī)控制指令作說明,有興趣者可自己查閱相關(guān)書籍;
數(shù)據(jù)傳送指令:
這種指令負(fù)責(zé)把數(shù)據(jù)、地址或者立即數(shù)傳送到寄存器或者存儲(chǔ)單元中,有以下五類,分別作以下說明;
1、通用數(shù)據(jù)傳送指令
mov傳送指令:
格式:mov ? ? dst,src;
執(zhí)行的操作:(dst)←(src);其中,dst為目的操作數(shù),src為原操作數(shù);
? ? ? ?在此指令中需要注意以下規(guī)則:兩個(gè)操作數(shù)不能同時(shí)為存儲(chǔ)單元、立即數(shù)不能作為目的操作數(shù)使用、不能在兩個(gè)段寄存器間傳送信息,立即數(shù)不能直接送至段寄存器、目的操作數(shù)不允許用cs寄存器;另外以下是允許操作類型:寄存器到寄存器、立即數(shù)到寄存器、立即數(shù)到存儲(chǔ)單元、存儲(chǔ)單元到寄存器、寄存器到存儲(chǔ)單元、寄存器或存儲(chǔ)單元到除cs段外的任何段寄存器;此指令不影響標(biāo)志位;
如 mov ? ? ax,data_seg ? ? ? mov ? ? ds,ax
push進(jìn)棧:
格式:push src
執(zhí)行操作:
16位指令(sp)←(sp)-2
? ? ? ? ? ? ? ?((sp+1),(sp))←(src)
如: ?push ax
執(zhí)行情況如下: ? ? ?
注意此操作不能用立即數(shù)方式;
pop出棧指令:
格式: ? ?格式:pop dst
執(zhí)行操作:
16位指令(dst)←((sp+1),(sp))
? ? ? ? ? ? ?(sp)←(sp)+2
如: ? pop ax
執(zhí)行如下:
注意此操作目的操作數(shù)不允許用立即數(shù)和cs段寄存器; ?
xchg交換指令:
格式:xchg opr1,opr2
執(zhí)行操作:(opr1)與(opr2)內(nèi)容互換
此指令不允許使用立即數(shù)方式,不允許使用段寄存器,而且必須有一個(gè)操作數(shù)為寄存器,不影響標(biāo)志位;如:
xchg bx,[bp+si]
2、累加器專用傳送指令
? ? ? 這組指令實(shí)現(xiàn)在I/O端口和CPU之間傳送信息,且CPU接收信息的寄存器只限于AX和AL;外部設(shè)備利用i/O端口號(hào)來收發(fā)信息,i/o端口號(hào)最多可有65536個(gè)i/o端口,其中前256個(gè)端口(0~0FFH)可以直接在指令中指定,此時(shí)指令用兩個(gè)字節(jié)表示,第二個(gè)字節(jié)就是要表示的端口號(hào),這種方式稱為長(zhǎng)格式;另外,當(dāng)端口號(hào)>=256時(shí),只能使用短格式,必須將端口號(hào)先傳送到DX寄存器,然后將DX的內(nèi)容傳送到AX、AL或者EAX寄存器中;
? ? ? 這組指令不影響標(biāo)志位;
in輸入指令:
長(zhǎng)格式:in al,port(字節(jié))、in ax,port(字);
執(zhí)行的操作:(al)←(port)(字節(jié))、(ax)←((port+1),(port))(字);
短格式:in al,dx(字節(jié))、in ax,dx(字);
執(zhí)行的操作:(al)←((dx))(字節(jié))、(ax)←((dl+1),(dl));
長(zhǎng)格式如:in ax,28h
短格式如:
mov dx,3FCH ? ?
in ax,dx
out輸出指令:
長(zhǎng)格式:out port,al(字節(jié))、out port,ax(字);
執(zhí)行的操作:(port)←(al)(字節(jié))、((port+1),(port))←(ax)(字);
短格式:out dx,al(字節(jié))、out dx,ax(字);
執(zhí)行的操作:((dx))←(al)(字節(jié))、((dl+1),(dl))←(ax);
長(zhǎng)格式如:out 28h,al
短格式如:
mov dx,ax
out 3FCH,dx
3、地址傳送指令
LEA(load effective address)有效地址送寄存器指令
? ? 這種方式實(shí)現(xiàn)把源操作的有效地址傳送到寄存器中,注意此種方式的源操作數(shù)的尋址方式只能使用出立即數(shù)和寄存器之外的存儲(chǔ)器尋址方式的任意一種;目的操作數(shù)可使用16位的除段寄存器之外的寄存器;此指令不影響標(biāo)志位;
格式:lea bx,[bx+si+0F62H]
如執(zhí)行之前(bx)=0400H,(si)=003cH
執(zhí)行后:(bx)=0400+003c+0f62=139eh
辨異:上述例子是把源操作數(shù)的有效地址送到bx中,mov bx,[bx+si+0F62H]則是把源操作數(shù)指定的存儲(chǔ)單元的內(nèi)容送到bx中,需要計(jì)算物理地址;
LDS(load ds with pointer)、LES(load es with pointer)指針?biāo)图拇嫫髦噶?/b>
? ? ? 這種方式的源操作數(shù)只能用于存儲(chǔ)器尋址的任一種方式,且目的操作數(shù)的寄存器不能使用段寄存器;該指令是把源操作數(shù)的指定的存儲(chǔ)單元的內(nèi)容送到目的操作數(shù)中,再把源操作數(shù)存儲(chǔ)單元的下一個(gè)存儲(chǔ)單元的內(nèi)容送到指定的存儲(chǔ)器中;另外這組指令不影響標(biāo)志位;以LDS指令為例,LES指令操作和LDS操作原理相同,只是指定的寄存器不同;
格式:LDS REG,SRC
執(zhí)行的操作:
(REG)←(SRC),(DS)←(SRC+2)
如:LES DI,[BX]
執(zhí)行前:(DS)=B000H,(BX)=080AH,(0B080AH)=05AEH,(0B080CH)=4000h
執(zhí)行后:(DI)=05AEH,(ES)=4000H
4、標(biāo)志寄存器傳送指令
LAHF(load ah with flags)標(biāo)志送AH
格式:lahf ? ? ?
執(zhí)行的操作:(ah)←(flags的低字節(jié))
SAHF(store ah into flags)AH標(biāo)志送至flags寄存器
格式:sahf
執(zhí)行的操作:(flags的低字節(jié))←(ah)
另還有pushf/pushfd、popf/popfd此處不作介紹,注意這組指令不影響標(biāo)志位;
5、類型轉(zhuǎn)換指令
CBW(convert byte to word) 字節(jié)轉(zhuǎn)換為字指令
格式:cbw
執(zhí)行的操作:將al中的內(nèi)容擴(kuò)展到ah中,若(al)最高有效位為0,(ah)為0;若(al)的最高有效位為1,則(ah)為0FFH;
算術(shù)指令:
? ? ? 該指令有雙操作數(shù)和單操作數(shù)之分,雙操作數(shù)不允許目的操作數(shù)和源操作數(shù)同時(shí)為存儲(chǔ)器尋址方式單操作數(shù)不允許使用立即數(shù)方式;
1、加法指令
ADD(add)加法:
格式:add dst,src
執(zhí)行的操作:(dst)←(dst)+(src)
此操作影響標(biāo)志位;
ADC(add with carry)帶進(jìn)位加法:
格式:adc dst,src
執(zhí)行的操作:(dst)←(dst)+(src)+cf;cf為帶進(jìn)位的值;
此操作影響標(biāo)志位;
INC(increment)加1:
格式:inc opr
執(zhí)行的操作:(opr)←(opr)+1
此操作不影響標(biāo)志位;
? ? ? 上面指令提到add和adc指令影響標(biāo)志位,標(biāo)志位中最主要的是of(overflow flag)溢出標(biāo)志、cf(carry flag)進(jìn)位標(biāo)志、zf(zero flag)零標(biāo)志、sf(sign flag)符號(hào)標(biāo)志;其中當(dāng)結(jié)果為零時(shí)zf為1,否則為0;結(jié)果為負(fù)時(shí)sf為1,否則為0;考慮of位時(shí)須把操作數(shù)當(dāng)成有符號(hào)數(shù)看待,對(duì)于加法來講,若操作數(shù)符號(hào)相同結(jié)果的符號(hào)與之相反則of置為1,否則置為0;考慮cf位時(shí)須把操作數(shù)當(dāng)成無(wú)符號(hào)數(shù)看待,最高有效位有進(jìn)位時(shí)置為1,否則置為0;如下例:
add dx,0F0F0H;執(zhí)行前(dx)=4652h
操作如下:0100 0110 0101 0010
? ? ? ? ? ? ? ? ? ?+1111 0000 1111 0000
=0011 0111 0100 0010(有進(jìn)位1)
看作有符號(hào)數(shù): ?則運(yùn)算前符號(hào)相反故of=0,看作無(wú)符號(hào)數(shù):有進(jìn)位故cf=1;結(jié)果符號(hào)為正故sf=0;結(jié)果不為零故zf=0;
2、減法指令
SUB(subtract)減法指令:
格式:sub dst,src
執(zhí)行的操作:(dst)←(dst)-(src);此操作影響標(biāo)志位;
SBB(subtract with borrow)帶借位減法:
格式:sub dst,src
執(zhí)行的操作:(dst)←(dst)-(src)-cf;此操作影響標(biāo)志位;
DEC(decrement)減1指令:
格式:dec opr
執(zhí)行的操作:(opr)←(opr)-1;此操作不影響cf標(biāo)志位;
CMP(compare)比較指令:
格式:cmp opr1,opr2
執(zhí)行的操作:(opr1)-(opr2);此操作影響條件標(biāo)志位;
? ? ? 現(xiàn)在來說說減法對(duì)標(biāo)志位的影響;對(duì)于zf和sf的設(shè)置同加法指令相同,這里不再贅述;設(shè)置of位時(shí),把操作數(shù)看作有符號(hào)數(shù),若被減數(shù)與減數(shù)的符號(hào)相反結(jié)果與減數(shù)的符號(hào)相同的話則of位置為1,否則置為1;設(shè)置cf位時(shí),把操作數(shù)看作無(wú)符號(hào)數(shù),若被減數(shù)<減數(shù)則cf置為1,否則置為0;如下例:
sub [si+14H],0136H;
指令執(zhí)行之前(ds)=3000H,(si)=0040h,(30054h)=4336h;
如下:0100 0011 0011 0110
? ? ? ? ? ?-0000 0001 0011 0110
? ? ? ? ? =0100 0010 0000 0000
? ? ?作如下判斷:結(jié)果不為零則zf位為0,結(jié)果為正則sf置為0,當(dāng)成無(wú)符號(hào)數(shù)看待被減數(shù)>減數(shù)則cf置為0,當(dāng)成有符號(hào)數(shù)看待,被減數(shù)與減數(shù)的符號(hào)相同,故of置為0;
3、乘法指令
指令中的源操作數(shù)的尋址方式可以是初立即數(shù)以外的任意一種方式;目的操作數(shù)為累加器;
MUL(unsigned multiple):無(wú)符號(hào)數(shù)乘法
格式:mul src
執(zhí)行的操作:源操作數(shù)為8位則相乘得到的16位存放到AX,AH存放高位字節(jié),AL存放低位字節(jié);源操作數(shù)為16位時(shí),結(jié)果存放到DX和AX中,DX存放高位,AX存放低位;此操作影響of位和cf位其它條件標(biāo)志位沒有定義;
iMUL(signed multiple):有符號(hào)數(shù)乘法
格式:imul src
執(zhí)行的操作:和有符號(hào)數(shù)相同,不過此操作必須是帶符號(hào)數(shù);
? ? ? 乘法對(duì)標(biāo)志位的影響如下:對(duì)于無(wú)符號(hào)數(shù)來講,若乘積的高一半為零則cf=of=0,否則為1;對(duì)于有符號(hào)數(shù)來講,若乘積的高一半是低一半的字節(jié)的符號(hào)擴(kuò)展,則cf=of=0,否則為1;如下例:
mul bl;指令執(zhí)行前(al)=0B4H,(bl)=11H;
執(zhí)行的結(jié)果為:0000 1011 1111 0100
結(jié)果的前一半不全為零,故cf=of=1;
4、除法指令
指令中的源操作數(shù)的尋址方式可以是初立即數(shù)以外的任意一種方式;目的操作數(shù)為累加器;
DIV(unsigned divided)無(wú)符號(hào)數(shù)除法指令:
格式:div src
執(zhí)行的操作:若除數(shù)為8位,則被除數(shù)為16位且保存在ax中,相除得到的結(jié)果的8位商保存在al中,得到的8位余數(shù)保存在ah中;若除數(shù)為16位,則被除數(shù)為32位,高位保存在DX寄存器中,低位保存在AX中,相除得到的結(jié)果的16位商保存在ax中,得到的16位的余數(shù)保存在dx中;此指令對(duì)所有的條件碼均無(wú)定義;
IDIV(signed divided)帶符號(hào)數(shù)除法指令:
格式:idiv src
執(zhí)行的操作:和div相同,但要求操作數(shù)必須為帶符號(hào)數(shù),商和余數(shù)也都是帶符號(hào)數(shù),且余數(shù)的符號(hào)和被除數(shù)相同;對(duì)所有的條件碼均無(wú)定義;
邏輯指令:
1、邏輯運(yùn)算指令
AND(and)邏輯與指令
格式:and dst,src
執(zhí)行的操作為(dst)←(dst)∧(src);
OR(or)邏輯或指令
格式:or dst,src
執(zhí)行的操作為(dst)←(dst)∨(src);
XOR(exclusive or)邏輯或指令
格式:xor dst,src
執(zhí)行的操作為(dst)←(dst)?(src);
TEST(test)測(cè)試指令
格式:test opr1,opr2
執(zhí)行的操作:(opr1)∩(opr2);結(jié)果不保存,為了置條件碼;
以上指令中,not指令不影響標(biāo)志位,且操作符不能為立即數(shù);其余指令兩個(gè)操作數(shù)的尋址方式不能同時(shí)為存儲(chǔ)器尋址,且執(zhí)行后使of和cf置為0,af無(wú)定義,其余位根據(jù)結(jié)果設(shè)置;上面的指令對(duì)于處理操作數(shù)相應(yīng)位比較有用,如要求屏蔽操作數(shù)的某些位只需利用add指令將源操作數(shù)相應(yīng)位置為0,其余位置為1即可;要求將操作數(shù)的某些位置為1,則使用or指令令源操作數(shù)的相應(yīng)位置為1,其余位置為0即可;要求測(cè)試某些位是否為1,利用test指令將相應(yīng)位置為1,其余位置為零,若結(jié)果cf=of=0,zf=1,sf=0則測(cè)試的位不為1;要求對(duì)目的操作數(shù)的某些位取反,則需用xor指令將源操作數(shù)的相應(yīng)位置為1即可;
2、移位指令
? ? ?以下指令的opr部分可以用除立即數(shù)以外的任意一種尋址方式,當(dāng)移位次數(shù)為1時(shí)可用立即數(shù)1代替cnt符號(hào),當(dāng)移位次數(shù)超過1時(shí),最好把需要移動(dòng)的位數(shù)送到CL中然后將CL代替CNT符號(hào)即可;
SHL(shift logical left)邏輯左移
格式:shl opr,cnt
執(zhí)行的操作如圖:
SAL(shift arithmetic left)算術(shù)左移
格式:sal opr,cnt
執(zhí)行操作和邏輯左移相同;
SHR(shift right)邏輯右移
格式:shr opr,cnt
執(zhí)行操作如圖:
SAR(shift arithmetic right)算術(shù)右移
格式:sar opr,cnt
執(zhí)行操作如圖:
ROL(rotat left)循環(huán)左移
格式:rol opr,cnt
執(zhí)行操作如下:
ROR(rotat right)循環(huán)右移
格式:ror opr,cnt
執(zhí)行操作如圖:
RCL(rotat left through carry)帶進(jìn)位循環(huán)左移
格式:rcl opr,cnt
執(zhí)行操作如圖:
RCR(rotat right through carry)帶進(jìn)位循環(huán)右移
格式:RCR opr,cnt
執(zhí)行操作如下:
上述指令對(duì)于cf位的影響如圖,當(dāng)cnt為1時(shí),of條件標(biāo)志有定義,否則有定義,移位過后當(dāng)最高有效位發(fā)生變化時(shí)of位置為1,否則置為0;另外上述指令對(duì)于AF位無(wú)定義:
串處理指令:
這一系列指令根據(jù)組合使用可分為兩組,以下做詳細(xì)說明;
(一)、與rep指令組合使用的有movs,stos,lods,ins和outs指令
REP(repeat)重復(fù)指令
格式:rep string primitive
執(zhí)行的操作:string primitive是指movs.stos.lods.ins指令,當(dāng)要執(zhí)行重復(fù)操作時(shí),需要先將重復(fù)次數(shù)送入cx寄存器中;執(zhí)行一次重復(fù)指令cx內(nèi)容減1,直到cx內(nèi)容為0停止執(zhí)行;
MOVS(move string)串傳送指令
指令:movs dst,src
執(zhí)行的操作:((di))←((si))
指令movsb(字節(jié)) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
執(zhí)行的操作:((di))+/-1←((si))+/-1
指令:movsw(字) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
執(zhí)行的操作:((di))+/-2←((si))+/-2
? ? ? 說明:此指令的功能是將SI寄存器指向的單元中的內(nèi)容傳送到DI指向的單元中,可順序存儲(chǔ)(DF=0,用cld指令設(shè)置),也可倒序存儲(chǔ)(DF=1,用sed指令設(shè)置),使用此指令之前還需要將源串的偏移地址(倒序存儲(chǔ)采用串的末地址)移到SI寄存器中,另外源串的段地址(倒序存儲(chǔ)采用串的末地址)必須要送至數(shù)據(jù)段寄存器中也可使用段跨越前綴指定段寄存器;另外還需處理的是目的串的首地址(倒序存儲(chǔ)采用串的末地址)送至DI寄存器中,目的串的段地址送至附加段中;該指令不影響條件碼;
LODS(load from string)從串取指令
指令:lods(字節(jié))
執(zhí)行的操作:(al)←((si))
指令:lodsw(字)
執(zhí)行的操作:(ax)=(al),(ah)←((si),(si+1))
操作說明:此指令的功能是將si指向的單元中的內(nèi)容傳送到AX或AL寄存器,可順序存(DF=0,用cld指令設(shè)置),也可倒序存(DF=1,用sed指令設(shè)置),使用此指令之前還需要將源串的首地址(倒序存儲(chǔ)采用串的末地址)送至sI寄存器中,目的串的段地址送至數(shù)據(jù)段中,允許使用段跨越來修改源段的段寄存器;該指令不影響條件碼;該指令一般不經(jīng)常和rep指令連用;
INS(input from port to string)串輸入指令
指令:insb(字節(jié))
執(zhí)行的操作:((di))+/-1←((dx))
指令:insw(字)
執(zhí)行的操作:((di))+/-2←((dx))
說明:把端口號(hào)內(nèi)的內(nèi)容存到指定的串單元中;
OUTS(output string to port)串輸入指令
指令:outsb(字節(jié))
執(zhí)行的操作:((dx))←((si))+/-1
指令:outsw(字)
執(zhí)行的操作:((dx))←((si))+/-2
說明:把源串里的內(nèi)容送至端口號(hào)內(nèi);
(二)與REPZ/REPE(repeat while equal/zero)和REPNE/REPNZ(repeat while not equal/zero)連用的CMPS(compare string)和SCAS(scan string) ? ? ?
REPZ/REPE當(dāng)相等/為零時(shí)重復(fù)串操作
格式:repz/repe string primitive
string primitive可為cmps或scas指令
執(zhí)行的操作:退出條件為zf=0(比較結(jié)果不為零即不相等此時(shí)cf標(biāo)志位為0)或者cx循環(huán)次數(shù)為零,其余的操作和rep執(zhí)行情況相同;
REPNZ/REPNE當(dāng)相等/為零時(shí)重復(fù)串操作
格式:repnz/repne string primitive
string primitive可為cmps或scas指令
執(zhí)行的操作:退出條件為zf=1(比較結(jié)果為零即量比較數(shù)相等此時(shí)cf標(biāo)志位為0)或者cx循環(huán)次數(shù)為零,其余的操作和rep執(zhí)行情況相同;
CMPS串比較指令
指令:cmpsb(字節(jié))
執(zhí)行的操作:將目的串和源串的相應(yīng)字節(jié)相減,但不保存結(jié)果,只根據(jù)結(jié)果設(shè)置標(biāo)志位;其余情況和movb相同;
指令:cmpsw(字)
執(zhí)行的操作:將目的串和源串的相應(yīng)字相減,但不保存結(jié)果,只根據(jù)結(jié)果設(shè)置標(biāo)志位;其余情況和movb相同;
SCAS串掃描指令
指令:scasb(字節(jié))
執(zhí)行的操作:將AL寄存器里的內(nèi)容和附加段目的串的字節(jié)相比較,但不保存結(jié)果,只根據(jù)結(jié)果設(shè)置標(biāo)志位,其余情況和movs指令相同;
指令:scasw(字)
執(zhí)行的操作:將AX寄存器里的內(nèi)容和附加段目的串的字相比較,但不保存結(jié)果,只根據(jù)結(jié)果設(shè)置標(biāo)志位,其余情況和movs指令相同;
控制轉(zhuǎn)移指令:
這部分內(nèi)容主要由無(wú)條件轉(zhuǎn)移指令、條件轉(zhuǎn)移指令、循環(huán)指令和子程序構(gòu)成,其余在這里不作介紹;另外無(wú)條件轉(zhuǎn)移指令在8086的尋址方式里已經(jīng)介紹過,此處也不再贅述;
1、條件轉(zhuǎn)移指令
這部分指令的opr部分使用了相對(duì)尋址方式,只能使用段內(nèi)的短轉(zhuǎn)移和近轉(zhuǎn)移,若要進(jìn)行段間的轉(zhuǎn)移則要使用jmp指令;該部分指令不影響條件碼,只根據(jù)一次運(yùn)算的結(jié)果設(shè)置的條件判斷是否需要進(jìn)行跳轉(zhuǎn);條件轉(zhuǎn)移指令可分為三類如下:
(1)根據(jù)單個(gè)條件標(biāo)志的設(shè)置情況判斷是否轉(zhuǎn)移;
JZ/JE(jump if zero/equal)結(jié)果為零或者相等則進(jìn)行轉(zhuǎn)移
格式:jz\je opr
測(cè)試條件:zf=1
JNZ/JNE(jump if not zero/equal)結(jié)果不為零或者不相等則進(jìn)行轉(zhuǎn)移
格式:jnz\jne opr
測(cè)試條件:zf=0
JS(jump if sign)結(jié)果為負(fù)轉(zhuǎn)移指令
格式:js opr
測(cè)試條件:sf=1
JNS(jump if not sign)結(jié)果不為負(fù)則進(jìn)行轉(zhuǎn)移
格式:jns opr
測(cè)試條件:sf=0
JO(jump if overflow)溢出則轉(zhuǎn)移
格式:jo opr
測(cè)試條件:of=1
JNO(jump if not overflow)溢出則轉(zhuǎn)移
格式:jno opr
測(cè)試條件:of=0
JB/JNAE/JC(jump if below,or not above or equal,or carry)低于,不高于或者進(jìn)位為1轉(zhuǎn)移指令
格式:jb/jnae/jc opr
測(cè)試條件:cf=1
JNB/JAE/JNC(jump if not below,or above or equal,or not carry)不低于,或者高于或者進(jìn)位為零轉(zhuǎn)移指令
格式:jnb/jae/jnc opr
測(cè)試條件:cf=0
2、比較兩個(gè)無(wú)符號(hào)數(shù),根據(jù)比較結(jié)果判斷是否轉(zhuǎn)移(高低用below或者above表示)
JB/JNAE/JC、JNB/JAE/jNC指令和上述情況相同;
JBE/JNA(jump if below or equal,or not above)比較結(jié)果為<=時(shí)轉(zhuǎn)移
格式:jbe/jna opr
測(cè)試條件:cf∪zf=1
JNBE/JA(jump if not below or equal,or above)比較結(jié)果為>時(shí)轉(zhuǎn)移
格式:jnbe/ja opr
測(cè)試條件:cf∪zf=0
3、比較兩個(gè)有符號(hào)數(shù),高低用greater和less表示
JL/JNGE(jump if less,or not greater equal)比較結(jié)果為<時(shí)轉(zhuǎn)移指令
格式:jl/jnge opr
測(cè)試條件:sf?of=1
JNL/JGE(jump if not less,or greater or equal)比較結(jié)果為>=時(shí)轉(zhuǎn)移指令
格式:jnl/jge opr
測(cè)試條件:sf?of=0
JLE/JNG(jump if less or equal,or not greater)比較結(jié)果為<=時(shí)轉(zhuǎn)移指令
格式:jle/jng opr
測(cè)試條件:sf?of∪zf=1
JNLE/JG(jump if not less equal,or greater)比較結(jié)果為>時(shí)轉(zhuǎn)移指令
格式:jnle/jg opr
測(cè)試條件:sf?of∪zf=0
2、循環(huán)指令
循環(huán)指令和串操作的重復(fù)指令相差不大,只是循環(huán)的可能是一段程序而不是只針對(duì)字符操作,循環(huán)的比較結(jié)果也循序標(biāo)志位,另外循環(huán)操作次數(shù)也需要提前存入cx寄存器中,循環(huán)指令的opr部分則是使用8位位移量與當(dāng)前ip寄存器內(nèi)容相加,即相當(dāng)于段內(nèi)直接短轉(zhuǎn)移;該指令不影響條件碼指令如下:
LOOP(loop)循環(huán)指令
格式:loop opr
測(cè)試條件:cx≠0
LOOPZ/LOOPE(loop if zf=0)當(dāng)結(jié)果為零即判斷結(jié)果相等則執(zhí)行循環(huán)
格式:loopz/loope opr
測(cè)試條件:cx≠0或者zf=1
LOOPNZ/LOOPNE(loop if zf=0)當(dāng)結(jié)果為零即判斷結(jié)果相等則執(zhí)行循環(huán)
格式:loopnz/loopne opr
測(cè)試條件:cx≠0或者zf=0
3、子程序指令
? ? ? 和高級(jí)語(yǔ)言相同的是匯編語(yǔ)言也提供了可以編寫具有特定功能的程序,稱為子程序;子程序由主程序通過CALL指令調(diào)用,在子程序的末尾設(shè)置RET指令用來當(dāng)子程序執(zhí)行完之后返回主程序;子程序可以和主程序設(shè)置在同一段中,也可以設(shè)置在不同段中,故CALL和RET指令就有不同的操作類型,這部分指令可以類比跳轉(zhuǎn)指令來看待,只是多了一部分的在堆棧中保存主程序的返回地址,這部分指令不影響條件碼;以下分別來說明:
(1)、CALL調(diào)用指令
段內(nèi)直接近調(diào)用
格式:CALL DST
執(zhí)行的操作:push(IP)
? ? ? ? ? ? ? ? ? ? (IP)←(IP)+位移量
說明:指令中的DST即是指子程序中的第一條指令的地址;操作的第一步是將當(dāng)前主程序的IP內(nèi)容(當(dāng)前主程序調(diào)用程序的下一條指令的地址)放置在棧中,第二步是將當(dāng)前(IP)內(nèi)容加上需要調(diào)用程序和當(dāng)前程序之間的位移量放置到(IP)中;
段內(nèi)間接近調(diào)用
格式:CALL DST
執(zhí)行的操作:push(IP)
? ? ? ? ? ? ? ? ? ?(IP)←(EA)
說明:指令中的DST可以使用初立即數(shù)之外的任意一種尋址方式;操作的第一步是將當(dāng)前主程序的IP內(nèi)容(當(dāng)前主程序調(diào)用程序的下一條指令的地址)放置在棧中,第二步是將按尋址方式尋找到的存儲(chǔ)單元中的有效地址放置到(IP)中;
段間直接遠(yuǎn)調(diào)用
格式:CALL DST
執(zhí)行的操作:push(CS) ? ? ? ? ? ?;主程序所在的段地址
? ? ? ? ? ? ? ? ? ? ?push(IP) ? ? ? ? ? ? ;返回主程序的有效地址
? ? ? ?(IP)←(EA);按DST的尋址方式尋找到的存儲(chǔ)單元內(nèi)的內(nèi)容作為子程序的有效地址
? ? ? ?(CS)←(EA+2);按DST的尋址方式尋找到的存儲(chǔ)單元的下一單元內(nèi)的內(nèi)容作為子程序的有效地址
(2)、返回指令
返回指令是將主程序存入棧中的內(nèi)容返回到IP和CS寄存器中,以便繼續(xù)執(zhí)行主程序的后續(xù)指令;如下
段內(nèi)近返回
格式:RET 執(zhí)行的操作,(IP)←POP()出棧操作
段內(nèi)帶立即數(shù)近返回
格式:RET EXP
執(zhí)行的操作:第一步執(zhí)行(IP)←POP(),第二步根據(jù)EXP表達(dá)式計(jì)算出的位移量修改棧頂指針,即(CS)←(CS)+位移量
段間近返回
格式:RET 執(zhí)行的操作,依次執(zhí)行(IP)←POP()出棧操作和(CS)←POP()出棧操作
段間帶立即數(shù)近返回
格式:RET EXP
執(zhí)行的操作:第一步執(zhí)行(IP)←POP()和(CS)←POP(),第二步根據(jù)EXP表達(dá)式計(jì)算出的位移量修改棧頂指針,即(CS)←(CS)+位移量