匯編語(yǔ)言的指令系統(tǒng)和尋址方式

? ? ? ? 計(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


OP表示操作碼3064為立即數(shù)

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í)行如圖:

指令保存以及執(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í)行如下

存儲(chǔ)以及執(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í)行情況如下:


指令存儲(chǔ)以及執(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;如下:

指令執(zhí)行以及存儲(chǔ)

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í)行如下:

指令存儲(chǔ)以及執(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);

段內(nèi)直接尋址

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]


段內(nèi)間接

注意:這里的轉(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í)行情況如下: ? ? ?

push操作

注意此操作不能用立即數(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í)行操作如圖:


算術(shù)右移

ROL(rotat left)循環(huán)左移

格式:rol opr,cnt

執(zhí)行操作如下:


循環(huán)左移

ROR(rotat right)循環(huán)右移

格式:ror opr,cnt

執(zhí)行操作如圖:


循環(huán)右移

RCL(rotat left through carry)帶進(jìn)位循環(huán)左移

格式:rcl opr,cnt

執(zhí)行操作如圖:


帶進(jìn)位循環(huán)左移

RCR(rotat right through carry)帶進(jìn)位循環(huán)右移

格式:RCR opr,cnt

執(zhí)行操作如下:


帶進(jìn)位循環(huán)右移

上述指令對(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)+位移量

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,283評(píng)論 6 530
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 97,947評(píng)論 3 413
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,094評(píng)論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,485評(píng)論 1 308
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,268評(píng)論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 54,817評(píng)論 1 321
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,906評(píng)論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,039評(píng)論 0 285
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,551評(píng)論 1 331
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,502評(píng)論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,662評(píng)論 1 366
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,188評(píng)論 5 356
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 43,907評(píng)論 3 345
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,304評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,563評(píng)論 1 281
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,255評(píng)論 3 389
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,637評(píng)論 2 370

推薦閱讀更多精彩內(nèi)容