匯編語言的指令系統和尋址方式

? ? ? ? 計算機通過執行指令序列來使機器得以工作,所以對于每一系列的計算機都有指定的一組指令集供計算機使用,這組指令集就叫做計算機的指令系統;指令可分為操作碼和操作數兩部分,計算機執行指令時將根據對應的二進制代碼識別操作碼并加以執行操作碼對應的操作;

? ? ? ? 操作數部分比較復雜,每一條指令可根據操作數的個數分為一地址指令、二地址指令和三地址指令,其中三地址指令中有兩個操作數是源操作數加以運算后的結果存放在第三個操作數對應的地址單元中;二地址指令是將兩個操作數運算過后的結果存放在第一個操作數對應的地址單元里,所以這種操作將會使一位操作數損失,若以后還需用到該操作數應加以提前保存副本;尋找操作數的方式相對的復雜一些,以下將做重點介紹。

? ? ? ? 另外匯編語言是一種符號語言,用助記符表示操作碼,用符號或者符號地址表示操作數,且每一條都與機器指令一一對應;這篇文章將從80X86的尋址方式、程序占有的空間和執行時間和80X86的指令系統三個方面進行說明;(以80X86講起)

一:80X86的尋址方式

? ? ? ? 有兩個方面:與數據有關的尋址方式和與轉移地址有關的尋址方式。數據尋址方式中將以MOV ? ? D,S為例,表示把源操作數S傳送到目的操作數D中;

數據尋址方式:

1、立即尋址方式

? ? ? 操作數直接存放在指令中,作為指令的一部分存放在代碼段中,并且緊跟在操作碼之后;這種方式常常用來表示常數,對寄存器進行賦值,源操作數的長度應該和目的操作數的長度一致;如:

MOV ? ? ?AX,3064H


OP表示操作碼3064為立即數

2、寄存器尋址方式

? ? ? ? 操作數在寄存器中,不需要訪問存儲器,所以有較高的運算速度;如:

MOV ? ? AX,BX

若執行前(AX)=3064H,(BX)=1234H,執行后(AX)=(BX)=1234H


寄存器尋址方式


3、直接尋址方式

? ? ? 這種方式操作數的有效地址只有位移量一種成分;如:

MOV ? ? AX,[2000H]

如果(DS)=3000好,執行如圖:

指令保存以及執行情況

另:用符號地址代替數值地址

MOV ? ? AX,VALUE和MOV ? ? AX,[VALUE]是等效的

4、寄存器間接尋址方式

? ? ? ? 操作數的有效地址只包含基址寄存器或者變趾寄存器內容一種成分;另外,16位尋址時除BP寄存器默認段寄存器為SS外,其它的默認寄存器為DS;

如:MOV ? ? AX,[BX]

若(DS)=2000H,(BX)=1000H,則:物理地址=20000+1000=21000H,結果為(AX)=50A0H;執行如下

存儲以及執行情況


5、寄存器相對尋址方式

? ? ? ? 操作數的有效地址為基址寄存器或變址寄存器的內容與指令中指定的位移量兩種成分構成,即兩種成分相加即為有效地址;

如:MOV ? ? AX,COUNT[SI]

也可以表示為MOV ? ? AX,[count+si](不區分大小寫);若:(ds)=3000h,(si)=2000h,count=3000h,物理地址=30000+2000+3000=35000H,執行結果(ax)=1234h;執行情況如下:


指令存儲以及執行情況

6、基址變址尋址方式

? ? ? 操作數的有效地址有兩種成分構成,即變址寄存器內容和基址寄存器內容之和;

如:mov ? ? ax,[bx][di]或者寫為mov ? ? ax,[bx+di];若(ds)=2100h,(bx)=0158h,di=10A5h;物理地址=21000+0158+10A5=221FDH;執行結果(ax)=1234H;如下:

指令執行以及存儲

7、相對基址變址尋址方式

操作數的有效地址是一個基址寄存器與一個變址寄存器的內容和指令中指定的位移量之和,故有三種成分構成;

如:mov ? ? ax,array[bx][si];若(ds)=3000h,(bx)=2000h,(si)=1000h,mask=0250h;物理地址=16d*3000+2000+1000+0250=33250h;執行如下:

指令存儲以及執行

與轉移地址有關的尋址方式:

1、段內直接尋址

? ? ? ? 轉向的有效地址為當前IP內容與指令中指定的8位或16位位移量之和;當用于條件轉移時,位移量只允許8位;當用于無條件轉移時,位移量為8位時表示段內短轉移,此時須在位移量之前加上short字符,如jmp ? ? short quest;無條件轉移位移量為16位時,稱為段內近轉移,須在位移量前加操作符near ptr,如:jmp ? ? near ptr quest;其中quest為位移量符號;

段內直接尋址

2、段內間接尋址

? ? ? ? 這種轉移轉向的有效地址是寄存器或者存儲單元里的內容,也就是將寄存器或者存儲單元里的內容取代以前IP寄存器里的內容;這種段內轉移指令不能作為條件轉移指令使用;如:

jmp ? ? bx

jmp ? ? word ptr[bp+table]


段內間接

注意:這里的轉向的有效地址是指根據尋址方式得到的存儲單元或者寄存器里的內容;

3、段間直接尋址

這種轉移方式除了將指令中指定的偏移地址取代IP寄存器里的內容外,還需要將指令中指定的內容所在的段地址取代cs段里內容,此時用far ptr操作符表示;如:

jmp ? ? far ptr nextroutint


段間直接

4、段間間接轉移

? ? ? ? 用存儲器里兩個連續的字來取代cs和ip的內容,此時存儲器里的內容可以用除立即數以外的任意一種數據尋址方式獲得;若用此方式須在指令中加以dword ptr字符,如:

jmp ? ? dword ptr[inters+bx]

段間間接


二、程序占有的空間和執行時間

? ? ? ?對于一條指令來說,若為16位則一條指令的長度可達到1至7個字節,而對于不同的尋址方式使用操作數也需要時間這就在空間和時間上有了限制,所以編制程序時應考慮這兩個因素使程序更加的精煉;

三、80X86的指令系統

? ? ? ? 此系列的指令系統可以分別為以下六組:數據傳送指令、串處理指令、算術指令、控制轉移指令、邏輯指令和處理機控制指令,此處不對處理機控制指令作說明,有興趣者可自己查閱相關書籍;

數據傳送指令:

這種指令負責把數據、地址或者立即數傳送到寄存器或者存儲單元中,有以下五類,分別作以下說明;

1、通用數據傳送指令

mov傳送指令:

格式:mov ? ? dst,src;

執行的操作:(dst)←(src);其中,dst為目的操作數,src為原操作數;

? ? ? ?在此指令中需要注意以下規則:兩個操作數不能同時為存儲單元、立即數不能作為目的操作數使用、不能在兩個段寄存器間傳送信息,立即數不能直接送至段寄存器、目的操作數不允許用cs寄存器;另外以下是允許操作類型:寄存器到寄存器、立即數到寄存器、立即數到存儲單元、存儲單元到寄存器、寄存器到存儲單元、寄存器或存儲單元到除cs段外的任何段寄存器;此指令不影響標志位;

如 mov ? ? ax,data_seg ? ? ? mov ? ? ds,ax

push進棧:

格式:push src

執行操作:

16位指令(sp)←(sp)-2

? ? ? ? ? ? ? ?((sp+1),(sp))←(src)

如: ?push ax

執行情況如下: ? ? ?

push操作

注意此操作不能用立即數方式;

pop出棧指令:

格式: ? ?格式:pop dst

執行操作:

16位指令(dst)←((sp+1),(sp))

? ? ? ? ? ? ?(sp)←(sp)+2

如: ? pop ax

執行如下:


出棧操作

注意此操作目的操作數不允許用立即數和cs段寄存器; ?

xchg交換指令:

格式:xchg opr1,opr2

執行操作:(opr1)與(opr2)內容互換

此指令不允許使用立即數方式,不允許使用段寄存器,而且必須有一個操作數為寄存器,不影響標志位;如:

xchg bx,[bp+si]

2、累加器專用傳送指令

? ? ? 這組指令實現在I/O端口和CPU之間傳送信息,且CPU接收信息的寄存器只限于AX和AL;外部設備利用i/O端口號來收發信息,i/o端口號最多可有65536個i/o端口,其中前256個端口(0~0FFH)可以直接在指令中指定,此時指令用兩個字節表示,第二個字節就是要表示的端口號,這種方式稱為長格式;另外,當端口號>=256時,只能使用短格式,必須將端口號先傳送到DX寄存器,然后將DX的內容傳送到AX、AL或者EAX寄存器中;

? ? ? 這組指令不影響標志位;

in輸入指令:

長格式:in al,port(字節)、in ax,port(字);

執行的操作:(al)←(port)(字節)、(ax)←((port+1),(port))(字);

短格式:in al,dx(字節)、in ax,dx(字);

執行的操作:(al)←((dx))(字節)、(ax)←((dl+1),(dl));

長格式如:in ax,28h

短格式如:

mov dx,3FCH ? ?

in ax,dx

out輸出指令:

長格式:out port,al(字節)、out port,ax(字);

執行的操作:(port)←(al)(字節)、((port+1),(port))←(ax)(字);

短格式:out dx,al(字節)、out dx,ax(字);

執行的操作:((dx))←(al)(字節)、((dl+1),(dl))←(ax);

長格式如:out 28h,al

短格式如:

mov dx,ax

out 3FCH,dx

3、地址傳送指令

LEA(load effective address)有效地址送寄存器指令

? ? 這種方式實現把源操作的有效地址傳送到寄存器中,注意此種方式的源操作數的尋址方式只能使用出立即數和寄存器之外的存儲器尋址方式的任意一種;目的操作數可使用16位的除段寄存器之外的寄存器;此指令不影響標志位;

格式:lea bx,[bx+si+0F62H]

如執行之前(bx)=0400H,(si)=003cH

執行后:(bx)=0400+003c+0f62=139eh

辨異:上述例子是把源操作數的有效地址送到bx中,mov bx,[bx+si+0F62H]則是把源操作數指定的存儲單元的內容送到bx中,需要計算物理地址;

LDS(load ds with pointer)、LES(load es with pointer)指針送寄存器指令

? ? ? 這種方式的源操作數只能用于存儲器尋址的任一種方式,且目的操作數的寄存器不能使用段寄存器;該指令是把源操作數的指定的存儲單元的內容送到目的操作數中,再把源操作數存儲單元的下一個存儲單元的內容送到指定的存儲器中;另外這組指令不影響標志位;以LDS指令為例,LES指令操作和LDS操作原理相同,只是指定的寄存器不同;

格式:LDS REG,SRC

執行的操作:

(REG)←(SRC),(DS)←(SRC+2)

如:LES DI,[BX]

執行前:(DS)=B000H,(BX)=080AH,(0B080AH)=05AEH,(0B080CH)=4000h

執行后:(DI)=05AEH,(ES)=4000H

4、標志寄存器傳送指令

LAHF(load ah with flags)標志送AH

格式:lahf ? ? ?

執行的操作:(ah)←(flags的低字節)

SAHF(store ah into flags)AH標志送至flags寄存器

格式:sahf

執行的操作:(flags的低字節)←(ah)

另還有pushf/pushfd、popf/popfd此處不作介紹,注意這組指令不影響標志位;

5、類型轉換指令

CBW(convert byte to word) 字節轉換為字指令

格式:cbw

執行的操作:將al中的內容擴展到ah中,若(al)最高有效位為0,(ah)為0;若(al)的最高有效位為1,則(ah)為0FFH;

算術指令:

? ? ? 該指令有雙操作數和單操作數之分,雙操作數不允許目的操作數和源操作數同時為存儲器尋址方式單操作數不允許使用立即數方式;

1、加法指令

ADD(add)加法:

格式:add dst,src

執行的操作:(dst)←(dst)+(src)

此操作影響標志位;

ADC(add with carry)帶進位加法:

格式:adc dst,src

執行的操作:(dst)←(dst)+(src)+cf;cf為帶進位的值;

此操作影響標志位;

INC(increment)加1:

格式:inc opr

執行的操作:(opr)←(opr)+1

此操作不影響標志位;

? ? ? 上面指令提到add和adc指令影響標志位,標志位中最主要的是of(overflow flag)溢出標志、cf(carry flag)進位標志、zf(zero flag)零標志、sf(sign flag)符號標志;其中當結果為零時zf為1,否則為0;結果為負時sf為1,否則為0;考慮of位時須把操作數當成有符號數看待,對于加法來講,若操作數符號相同結果的符號與之相反則of置為1,否則置為0;考慮cf位時須把操作數當成無符號數看待,最高有效位有進位時置為1,否則置為0;如下例:

add dx,0F0F0H;執行前(dx)=4652h

操作如下:0100 0110 0101 0010

? ? ? ? ? ? ? ? ? ?+1111 0000 1111 0000

=0011 0111 0100 0010(有進位1)

看作有符號數: ?則運算前符號相反故of=0,看作無符號數:有進位故cf=1;結果符號為正故sf=0;結果不為零故zf=0;

2、減法指令

SUB(subtract)減法指令:

格式:sub dst,src

執行的操作:(dst)←(dst)-(src);此操作影響標志位;

SBB(subtract with borrow)帶借位減法:

格式:sub dst,src

執行的操作:(dst)←(dst)-(src)-cf;此操作影響標志位;

DEC(decrement)減1指令:

格式:dec opr

執行的操作:(opr)←(opr)-1;此操作不影響cf標志位;

CMP(compare)比較指令:

格式:cmp opr1,opr2

執行的操作:(opr1)-(opr2);此操作影響條件標志位;

? ? ? 現在來說說減法對標志位的影響;對于zf和sf的設置同加法指令相同,這里不再贅述;設置of位時,把操作數看作有符號數,若被減數與減數的符號相反結果與減數的符號相同的話則of位置為1,否則置為1;設置cf位時,把操作數看作無符號數,若被減數<減數則cf置為1,否則置為0;如下例:

sub [si+14H],0136H;

指令執行之前(ds)=3000H,(si)=0040h,(30054h)=4336h;

如下:0100 0011 0011 0110

? ? ? ? ? ?-0000 0001 0011 0110

? ? ? ? ? =0100 0010 0000 0000

? ? ?作如下判斷:結果不為零則zf位為0,結果為正則sf置為0,當成無符號數看待被減數>減數則cf置為0,當成有符號數看待,被減數與減數的符號相同,故of置為0;

3、乘法指令

指令中的源操作數的尋址方式可以是初立即數以外的任意一種方式;目的操作數為累加器;

MUL(unsigned multiple):無符號數乘法

格式:mul src

執行的操作:源操作數為8位則相乘得到的16位存放到AX,AH存放高位字節,AL存放低位字節;源操作數為16位時,結果存放到DX和AX中,DX存放高位,AX存放低位;此操作影響of位和cf位其它條件標志位沒有定義;

iMUL(signed multiple):有符號數乘法

格式:imul src

執行的操作:和有符號數相同,不過此操作必須是帶符號數;

? ? ? 乘法對標志位的影響如下:對于無符號數來講,若乘積的高一半為零則cf=of=0,否則為1;對于有符號數來講,若乘積的高一半是低一半的字節的符號擴展,則cf=of=0,否則為1;如下例:

mul bl;指令執行前(al)=0B4H,(bl)=11H;

執行的結果為:0000 1011 1111 0100

結果的前一半不全為零,故cf=of=1;

4、除法指令

指令中的源操作數的尋址方式可以是初立即數以外的任意一種方式;目的操作數為累加器;

DIV(unsigned divided)無符號數除法指令:

格式:div src

執行的操作:若除數為8位,則被除數為16位且保存在ax中,相除得到的結果的8位商保存在al中,得到的8位余數保存在ah中;若除數為16位,則被除數為32位,高位保存在DX寄存器中,低位保存在AX中,相除得到的結果的16位商保存在ax中,得到的16位的余數保存在dx中;此指令對所有的條件碼均無定義;

IDIV(signed divided)帶符號數除法指令:

格式:idiv src

執行的操作:和div相同,但要求操作數必須為帶符號數,商和余數也都是帶符號數,且余數的符號和被除數相同;對所有的條件碼均無定義;

邏輯指令:

1、邏輯運算指令

AND(and)邏輯與指令

格式:and dst,src

執行的操作為(dst)←(dst)∧(src);

OR(or)邏輯或指令

格式:or dst,src

執行的操作為(dst)←(dst)∨(src);

XOR(exclusive or)邏輯或指令

格式:xor dst,src

執行的操作為(dst)←(dst)?(src);

TEST(test)測試指令

格式:test opr1,opr2

執行的操作:(opr1)∩(opr2);結果不保存,為了置條件碼;

以上指令中,not指令不影響標志位,且操作符不能為立即數;其余指令兩個操作數的尋址方式不能同時為存儲器尋址,且執行后使of和cf置為0,af無定義,其余位根據結果設置;上面的指令對于處理操作數相應位比較有用,如要求屏蔽操作數的某些位只需利用add指令將源操作數相應位置為0,其余位置為1即可;要求將操作數的某些位置為1,則使用or指令令源操作數的相應位置為1,其余位置為0即可;要求測試某些位是否為1,利用test指令將相應位置為1,其余位置為零,若結果cf=of=0,zf=1,sf=0則測試的位不為1;要求對目的操作數的某些位取反,則需用xor指令將源操作數的相應位置為1即可;

2、移位指令

? ? ?以下指令的opr部分可以用除立即數以外的任意一種尋址方式,當移位次數為1時可用立即數1代替cnt符號,當移位次數超過1時,最好把需要移動的位數送到CL中然后將CL代替CNT符號即可;

SHL(shift logical left)邏輯左移

格式:shl opr,cnt

執行的操作如圖:


邏輯左移

SAL(shift arithmetic left)算術左移

格式:sal opr,cnt

執行操作和邏輯左移相同;

SHR(shift right)邏輯右移

格式:shr opr,cnt

執行操作如圖:


邏輯右移

SAR(shift arithmetic right)算術右移

格式:sar opr,cnt

執行操作如圖:


算術右移

ROL(rotat left)循環左移

格式:rol opr,cnt

執行操作如下:


循環左移

ROR(rotat right)循環右移

格式:ror opr,cnt

執行操作如圖:


循環右移

RCL(rotat left through carry)帶進位循環左移

格式:rcl opr,cnt

執行操作如圖:


帶進位循環左移

RCR(rotat right through carry)帶進位循環右移

格式:RCR opr,cnt

執行操作如下:


帶進位循環右移

上述指令對于cf位的影響如圖,當cnt為1時,of條件標志有定義,否則有定義,移位過后當最高有效位發生變化時of位置為1,否則置為0;另外上述指令對于AF位無定義:

串處理指令:

這一系列指令根據組合使用可分為兩組,以下做詳細說明;

(一)、與rep指令組合使用的有movs,stos,lods,ins和outs指令

REP(repeat)重復指令

格式:rep string primitive

執行的操作:string primitive是指movs.stos.lods.ins指令,當要執行重復操作時,需要先將重復次數送入cx寄存器中;執行一次重復指令cx內容減1,直到cx內容為0停止執行;

MOVS(move string)串傳送指令

指令:movs dst,src

執行的操作:((di))←((si))

指令movsb(字節) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

執行的操作:((di))+/-1←((si))+/-1

指令:movsw(字) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

執行的操作:((di))+/-2←((si))+/-2

? ? ? 說明:此指令的功能是將SI寄存器指向的單元中的內容傳送到DI指向的單元中,可順序存儲(DF=0,用cld指令設置),也可倒序存儲(DF=1,用sed指令設置),使用此指令之前還需要將源串的偏移地址(倒序存儲采用串的末地址)移到SI寄存器中,另外源串的段地址(倒序存儲采用串的末地址)必須要送至數據段寄存器中也可使用段跨越前綴指定段寄存器;另外還需處理的是目的串的首地址(倒序存儲采用串的末地址)送至DI寄存器中,目的串的段地址送至附加段中;該指令不影響條件碼;

LODS(load from string)從串取指令

指令:lods(字節)

執行的操作:(al)←((si))

指令:lodsw(字)

執行的操作:(ax)=(al),(ah)←((si),(si+1))

操作說明:此指令的功能是將si指向的單元中的內容傳送到AX或AL寄存器,可順序存(DF=0,用cld指令設置),也可倒序存(DF=1,用sed指令設置),使用此指令之前還需要將源串的首地址(倒序存儲采用串的末地址)送至sI寄存器中,目的串的段地址送至數據段中,允許使用段跨越來修改源段的段寄存器;該指令不影響條件碼;該指令一般不經常和rep指令連用;

INS(input from port to string)串輸入指令

指令:insb(字節)

執行的操作:((di))+/-1←((dx))

指令:insw(字)

執行的操作:((di))+/-2←((dx))

說明:把端口號內的內容存到指定的串單元中;

OUTS(output string to port)串輸入指令

指令:outsb(字節)

執行的操作:((dx))←((si))+/-1

指令:outsw(字)

執行的操作:((dx))←((si))+/-2

說明:把源串里的內容送至端口號內;

(二)與REPZ/REPE(repeat while equal/zero)和REPNE/REPNZ(repeat while not equal/zero)連用的CMPS(compare string)和SCAS(scan string) ? ? ?

REPZ/REPE當相等/為零時重復串操作

格式:repz/repe string primitive

string primitive可為cmps或scas指令

執行的操作:退出條件為zf=0(比較結果不為零即不相等此時cf標志位為0)或者cx循環次數為零,其余的操作和rep執行情況相同;

REPNZ/REPNE當相等/為零時重復串操作

格式:repnz/repne string primitive

string primitive可為cmps或scas指令

執行的操作:退出條件為zf=1(比較結果為零即量比較數相等此時cf標志位為0)或者cx循環次數為零,其余的操作和rep執行情況相同;

CMPS串比較指令

指令:cmpsb(字節)

執行的操作:將目的串和源串的相應字節相減,但不保存結果,只根據結果設置標志位;其余情況和movb相同;

指令:cmpsw(字)

執行的操作:將目的串和源串的相應字相減,但不保存結果,只根據結果設置標志位;其余情況和movb相同;

SCAS串掃描指令

指令:scasb(字節)

執行的操作:將AL寄存器里的內容和附加段目的串的字節相比較,但不保存結果,只根據結果設置標志位,其余情況和movs指令相同;

指令:scasw(字)

執行的操作:將AX寄存器里的內容和附加段目的串的字相比較,但不保存結果,只根據結果設置標志位,其余情況和movs指令相同;

控制轉移指令:

這部分內容主要由無條件轉移指令、條件轉移指令、循環指令和子程序構成,其余在這里不作介紹;另外無條件轉移指令在8086的尋址方式里已經介紹過,此處也不再贅述;

1、條件轉移指令

這部分指令的opr部分使用了相對尋址方式,只能使用段內的短轉移和近轉移,若要進行段間的轉移則要使用jmp指令;該部分指令不影響條件碼,只根據一次運算的結果設置的條件判斷是否需要進行跳轉;條件轉移指令可分為三類如下:

(1)根據單個條件標志的設置情況判斷是否轉移;

JZ/JE(jump if zero/equal)結果為零或者相等則進行轉移

格式:jz\je opr

測試條件:zf=1

JNZ/JNE(jump if not zero/equal)結果不為零或者不相等則進行轉移

格式:jnz\jne opr

測試條件:zf=0

JS(jump if sign)結果為負轉移指令

格式:js opr

測試條件:sf=1

JNS(jump if not sign)結果不為負則進行轉移

格式:jns opr

測試條件:sf=0

JO(jump if overflow)溢出則轉移

格式:jo opr

測試條件:of=1

JNO(jump if not overflow)溢出則轉移

格式:jno opr

測試條件:of=0

JB/JNAE/JC(jump if below,or not above or equal,or carry)低于,不高于或者進位為1轉移指令

格式:jb/jnae/jc opr

測試條件:cf=1

JNB/JAE/JNC(jump if not below,or above or equal,or not carry)不低于,或者高于或者進位為零轉移指令

格式:jnb/jae/jnc opr

測試條件:cf=0

2、比較兩個無符號數,根據比較結果判斷是否轉移(高低用below或者above表示)

JB/JNAE/JC、JNB/JAE/jNC指令和上述情況相同;

JBE/JNA(jump if below or equal,or not above)比較結果為<=時轉移

格式:jbe/jna opr

測試條件:cf∪zf=1

JNBE/JA(jump if not below or equal,or above)比較結果為>時轉移

格式:jnbe/ja opr

測試條件:cf∪zf=0

3、比較兩個有符號數,高低用greater和less表示

JL/JNGE(jump if less,or not greater equal)比較結果為<時轉移指令

格式:jl/jnge opr

測試條件:sf?of=1

JNL/JGE(jump if not less,or greater or equal)比較結果為>=時轉移指令

格式:jnl/jge opr

測試條件:sf?of=0

JLE/JNG(jump if less or equal,or not greater)比較結果為<=時轉移指令

格式:jle/jng opr

測試條件:sf?of∪zf=1

JNLE/JG(jump if not less equal,or greater)比較結果為>時轉移指令

格式:jnle/jg opr

測試條件:sf?of∪zf=0

2、循環指令

循環指令和串操作的重復指令相差不大,只是循環的可能是一段程序而不是只針對字符操作,循環的比較結果也循序標志位,另外循環操作次數也需要提前存入cx寄存器中,循環指令的opr部分則是使用8位位移量與當前ip寄存器內容相加,即相當于段內直接短轉移;該指令不影響條件碼指令如下:

LOOP(loop)循環指令

格式:loop opr

測試條件:cx≠0

LOOPZ/LOOPE(loop if zf=0)當結果為零即判斷結果相等則執行循環

格式:loopz/loope opr

測試條件:cx≠0或者zf=1

LOOPNZ/LOOPNE(loop if zf=0)當結果為零即判斷結果相等則執行循環

格式:loopnz/loopne opr

測試條件:cx≠0或者zf=0

3、子程序指令

? ? ? 和高級語言相同的是匯編語言也提供了可以編寫具有特定功能的程序,稱為子程序;子程序由主程序通過CALL指令調用,在子程序的末尾設置RET指令用來當子程序執行完之后返回主程序;子程序可以和主程序設置在同一段中,也可以設置在不同段中,故CALL和RET指令就有不同的操作類型,這部分指令可以類比跳轉指令來看待,只是多了一部分的在堆棧中保存主程序的返回地址,這部分指令不影響條件碼;以下分別來說明:

(1)、CALL調用指令

段內直接近調用

格式:CALL DST

執行的操作:push(IP)

? ? ? ? ? ? ? ? ? ? (IP)←(IP)+位移量

說明:指令中的DST即是指子程序中的第一條指令的地址;操作的第一步是將當前主程序的IP內容(當前主程序調用程序的下一條指令的地址)放置在棧中,第二步是將當前(IP)內容加上需要調用程序和當前程序之間的位移量放置到(IP)中;

段內間接近調用

格式:CALL DST

執行的操作:push(IP)

? ? ? ? ? ? ? ? ? ?(IP)←(EA)

說明:指令中的DST可以使用初立即數之外的任意一種尋址方式;操作的第一步是將當前主程序的IP內容(當前主程序調用程序的下一條指令的地址)放置在棧中,第二步是將按尋址方式尋找到的存儲單元中的有效地址放置到(IP)中;

段間直接遠調用

格式:CALL DST

執行的操作:push(CS) ? ? ? ? ? ?;主程序所在的段地址

? ? ? ? ? ? ? ? ? ? ?push(IP) ? ? ? ? ? ? ;返回主程序的有效地址

? ? ? ?(IP)←(EA);按DST的尋址方式尋找到的存儲單元內的內容作為子程序的有效地址

? ? ? ?(CS)←(EA+2);按DST的尋址方式尋找到的存儲單元的下一單元內的內容作為子程序的有效地址

(2)、返回指令

返回指令是將主程序存入棧中的內容返回到IP和CS寄存器中,以便繼續執行主程序的后續指令;如下

段內近返回

格式:RET 執行的操作,(IP)←POP()出棧操作

段內帶立即數近返回

格式:RET EXP

執行的操作:第一步執行(IP)←POP(),第二步根據EXP表達式計算出的位移量修改棧頂指針,即(CS)←(CS)+位移量

段間近返回

格式:RET 執行的操作,依次執行(IP)←POP()出棧操作和(CS)←POP()出棧操作

段間帶立即數近返回

格式:RET EXP

執行的操作:第一步執行(IP)←POP()和(CS)←POP(),第二步根據EXP表達式計算出的位移量修改棧頂指針,即(CS)←(CS)+位移量

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容