• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            luqingfei@C++

            為中華之崛起而崛起!
            兼聽則明,偏聽則暗。

            匯編語言--標(biāo)志寄存器

             

            標(biāo)志寄存器

            CPU內(nèi)部的寄存器中,有一種特殊的寄存器(對于不同的處理機,個數(shù)和結(jié)構(gòu)都可能不同)具有三種作用:

            1) 用來存儲相關(guān)指令的某些執(zhí)行結(jié)果;

            2) 用來為CPU執(zhí)行相關(guān)指令提供行為依據(jù);

            3) 用來控制CPU的相關(guān)工作方式。

             

            這種特殊的寄存器在8086CPU中,被稱為標(biāo)志寄存器。8086CPU的標(biāo)志寄存器有16位,其中存儲的信息通常被稱為程序狀態(tài)字(PSW)。簡稱flag

            flag和其他寄存器不一樣,其他寄存器是用來存放數(shù)據(jù)的,都是整個寄存器具有一個含義。

            flag寄存器是按位起作用的,也就是說,它的每一位都有專門的含義,記錄特定的信息。

            15    14 13 12   11 10        9    8   7   6   5   4     3   2   1   0

             

             

             

             

            OF

            DF

            IF

            TF

            SF

            ZF

             

            AF

             

            PF

             

            CF

             

            flag13512131415位在8086CPU中沒有使用,不具有任何含義,而其余位都具有特殊的含義。

             

             

            ZF標(biāo)志

            flag的第6位是ZF,零標(biāo)志位。它記錄相關(guān)指令執(zhí)行后,其結(jié)果是否為0。如果結(jié)果為0,那么ZF=1,如果結(jié)果不為0,那么ZF=0

             

            mov ax,1

            sub ax,1

            執(zhí)行后,結(jié)果為0,則ZF=1,表示“結(jié)果是0”。

             

            mov ax,2

            sub ax,1

            執(zhí)行后,結(jié)果不為0,則ZF=0,表示“結(jié)果不是0”。

             

            在計算機中0表示邏輯假,表示否定,1表示邏輯真,表示肯定。

             

            注意,在8086CPU的指令集中,有的指令的執(zhí)行是影響標(biāo)志寄存器的,比如:addsubmuldivincorand等,它們大都是運算指令(進行邏輯或自述運算);有的指令的執(zhí)行對標(biāo)志寄存器沒有影響,比如:movpushpop等,它們大都是傳送指令。

             

            我們在使用一條指令的時候,要注意這條指令的全部功能,其中包括,執(zhí)行結(jié)果對標(biāo)記寄存器的哪些標(biāo)志位造成影響。

             

             

            PF標(biāo)志

            flag的第2位是PF,奇偶標(biāo)志位。它記錄相關(guān)指令執(zhí)行后,其結(jié)果的所有二進制位中1的個數(shù)是否為偶數(shù)。如果1的個數(shù)為偶數(shù),PF=1,如果為奇數(shù),那么PF=0

            比如:

            mov al,1

            add al,10

            執(zhí)行后,結(jié)果為00001011B,其中有3(奇數(shù))個1,則PF=0

             

             

            SF標(biāo)志

            flag的第7位是SF,符號標(biāo)志位。它記錄相關(guān)指令執(zhí)行后,其結(jié)果是否為負。如果結(jié)果為負,SF=1,如果非負,SF=0

             

            我們知道計算機中通常用補碼來表示有符號數(shù)據(jù)。計算機中的一個數(shù)據(jù)可以看作是有符號數(shù),也可以看成是無符號數(shù)。比如:

            00000001B,可以看作為無符號數(shù)1,或有符號數(shù)+1

            10000001B,可以看作為無符號數(shù)129,也可以看作有符號數(shù)-127

            這也就是說,對于同一個二進制數(shù)據(jù),計算機可以將它當(dāng)作無符號數(shù)據(jù)來運算,也可以當(dāng)作有符號數(shù)據(jù)來運算。比如:

            mov al,10000001B

            add al,1

            結(jié)果:(al)=10000010B

             

            我們可以將add指令進行的運算當(dāng)作無符號數(shù)的運算,那么add指令相當(dāng)于計算129+1,結(jié)果為13010000010B);也可以將add指令進行的運算當(dāng)作是有符號數(shù)的運算,那么add指令相當(dāng)于計算-127+1,結(jié)果為-12610000010B)。

             

            不管我們?nèi)绾慰创?/span>CPU在執(zhí)行add等指令的時候,就已經(jīng)包含了兩種含義,也將得到用同一種信息來記錄的兩種結(jié)果。關(guān)鍵在于我們在程序需要哪一種結(jié)果。

             

            SF標(biāo)志,就是CPU對有符號數(shù)運算結(jié)果的一種記錄,它記錄數(shù)據(jù)的正負。

            在我們將數(shù)據(jù)當(dāng)作有符號數(shù)來運算的時候,可以通過它來得知結(jié)果的正負。

            如果我們將數(shù)據(jù)當(dāng)作無符號數(shù)來運算,SF的值則沒有意義,雖然相關(guān)的指令影響了它的值。

             

            這也就是說,CPU在執(zhí)行add等指令時,是必須要影響到SF標(biāo)志位的值的。至于我們需不需要這種影響,那就看我們?nèi)绾慰创噶钏M行的運算了。

             

            某些指令將影響標(biāo)志寄存器中的多個標(biāo)志位,這些被影響的標(biāo)記位比較全面地記錄了指令的執(zhí)行結(jié)果,為相關(guān)的處理提供了所需的依據(jù)。

            比如指令sub al,al執(zhí)行后,ZFPFSF等標(biāo)志位都要受到影響,它們分別為:110,分別表示結(jié)果為零、結(jié)果二進制數(shù)1的個數(shù)為偶數(shù)、結(jié)果不為負數(shù)。

             

             

             

            CF標(biāo)志   [C,Carry進位、F,Flag標(biāo)志]

            flag的第0位是CF,進位標(biāo)志位。一般情況下,在進行了無符號運算的時候,它記錄了運算結(jié)果的最高有效位向更高位的進位值,或從更高位的借位值。

             

            對于倍數(shù)為N的無符號數(shù)來說,其對應(yīng)的二進制信息的最高位,即第N-1位,就是它的最高有效位,而假想存在的第N位,就是相對于最高有效位的更高位。

             

            當(dāng)兩個數(shù)據(jù)相加的時候,有可能產(chǎn)生從最高有效位向更高位的進位。

            由于這個進位值有可能無法保存,我們在前面的課程中,就只是簡單地說這個進位值丟失了,其實CPU在運算的時候,并不丟失這個進位值,而是記錄在一個特殊的寄存器的某一位上。8086CPU就用flagCF位來記錄這個進位值。

            比如:

            mov al,98H

            add al,al          ;執(zhí)行后,(al) = 30H, CF=1, CF記錄了從最高有效位向更高位的進位值

            add al,al     ;執(zhí)行后,(al) = 60H, CF=0, CF記錄了從最高有效位向更高位的進位值

             

            而當(dāng)兩個數(shù)據(jù)做減法的時候,有可能向更高位借位。比如,兩個8位數(shù)據(jù):97H-98H,將產(chǎn)生借位,借位后,相當(dāng)于計算197H-98H。而flagCF位也可以用來記錄這個借位值。

            比如:

            mov al,97H

            sub al,98H             ;執(zhí)行后,(al) = FFH, CF=1, CF記錄了向更高位的借位值

            sub al,al                 ;執(zhí)行后,(al)=0,CF=0CF記錄了向更高位的借位值

             

            OF標(biāo)志   [O,Overflow溢出,F,Flag標(biāo)志]

            溢出:在進行有符號數(shù)運算的時候,如結(jié)果超過了機器所能表示的范圍稱為溢出。

             

            那么,什么是機器所能表示的范圍呢?

            比如說,指令運算的結(jié)果用8位寄存器或內(nèi)存單元來存放,比如:add al,3,那么對于8位的有符號數(shù)據(jù),機器所能表示的范圍就是-128~127。同理,對于16位有符號數(shù),機器所能表示的范圍是-32768~32767

             

            注意,這里所講的溢出,只是對有符號數(shù)運算而言。

             

            由于在進行有符號數(shù)運算時,可能發(fā)生溢出而造成結(jié)果的錯誤,則CPU需要對指令執(zhí)行后是否產(chǎn)生溢出進行記錄。

             

            flag的第11位是OF,溢出標(biāo)志位。一般情況下,OF記錄了有符號數(shù)運算的結(jié)果是否發(fā)生了溢出。如果發(fā)生溢出,OF=1,如果沒有,OF=0

             

            一定要注意CFOF的區(qū)別:CF是對無符號數(shù)運算有意義的標(biāo)志位,而OF是對有符號數(shù)運算有意義的標(biāo)志位。

            比如:

            mov al,98d

            add al,99d

            add指令執(zhí)行后:CF=0OF=1

            CPU在執(zhí)行add等指令的時候,就包含了兩種含義:無符號數(shù)運算和有符號數(shù)運算。

            對于無符號數(shù)運算,CPUCF位來記錄是否產(chǎn)生了進位;

            對于有符號數(shù)運算,CPUOF位來記錄是否產(chǎn)生了溢出,

            當(dāng)然,還要用SF位來記錄結(jié)果的符號。

            對于無符號數(shù)運算,98+99沒有進位,CF=0

            對于有符號數(shù)運算,98+99發(fā)生溢出,OF=1

             

            CFOF所表示的進位和溢出,是分別對無符號數(shù)和有符號數(shù)運算而言的,它們之間沒有任何關(guān)系。

             

             

             

            adc指令

            adc是帶進位的加法指令,它利用了CF位上記錄的進位值。

            指令格式:adc 操作對象1,操作對象2

            功能:操作對象1=操作對象1+操作對象2+CF

            比如指令adc ax,bx 實現(xiàn)的功能是:(ax) = (ax) + (bx) +CF

            例:

            mov ax,2

            mov bx,1

            sub bx,ax

            adc ax,1

            執(zhí)行后,(ax) = 4adc執(zhí)行時,相當(dāng)于計算:(ax) + 1 + CF=2+1+1=4

             

            adc指令比add指令多加了一個CF位的值。

             

            為什么要加上CF的值呢?

            CPU為什么要提供這樣一條指令呢?

            CF的值的含義,在執(zhí)行adc指令的時候加上的CF的值的含義,由adc指令前面的指令決定的,也就是說,關(guān)鍵在于所加上的CF的值是被什么指令設(shè)置的。顯然,如果CF的值是被sub指令設(shè)置的,那么它的含義就是借位值;如果是被add指令設(shè)置的,那么它的含義就是進位值。

             

            加法可以分兩步來進行:(1)低位相加;(2)高位相加再加上低位相加產(chǎn)生的進位值。

            下面的指令和add ax,bx具有相同的結(jié)果:

            add al,bl

            adc ah,bh

             

            看來CPU提供的adc指令的目的,就是來進行加法的第二步運算的。

            adc指令和add指令相配合可以對更大的數(shù)據(jù)進行加法運算。

             

            舉例:編程,計算1EF000H+201000H,結(jié)果放在ax(高16位)和bx(低16位)中。

            因為兩個數(shù)據(jù)的位數(shù)都大于16,用add指令無法進行計算。我們將計算分兩步進行,先將低16位相加,然后將高16位和進位值相加。程序如下:

            mov ax,001EH              ;16

            mov bx,0f000H             ;16

            add bx,1000H               ;16位相加

            adc ax,0020H                ;16位相加,并加上CF進位值。

             

            adc指令執(zhí)行后,也可能產(chǎn)生進位值,所以也會對CF位進行設(shè)置。

            由于有這樣的功能,我們就可以對任意大的數(shù)據(jù)進行加法運算。

             

            incloop指令不影響CF位。

             

             

             

            sbb指令

            sbb是帶借位減法指令,它利用了CF位上記錄的借位值。

             

            指令格式:sbb 操作對象1,操作對象2

            功能:操作對象1=操作對象1-操作對象2-CF

            比如指令 sbb ax,bx 實現(xiàn)的功能是:(ax) = (ax) – (bx) – CF

             

            sbb指令執(zhí)行后,將對CF進行設(shè)置。

            利用sbb指令我們可以對任意大的數(shù)據(jù)進行減法運算。

            比如,計算003E1000H – 00202000H,結(jié)果放在ax,bx中,程序如下:

            mov bx,1000H

            mov ax,003EH

            sub bx,2000H        ;(bx) = (bx)-2000HCF設(shè)置借位數(shù) 1

            sbb ax,0020H         ;(ax) = (bx) – 0020H – CF

             

            sbbadc是基于同樣的思想設(shè)計的兩條指令,在應(yīng)用思路上和adc類似。

             

             

            cmp指令

            cmp是比較指令,cmp的功能相當(dāng)于減法指令,只是不保存結(jié)果。

            cmp指令執(zhí)行后,將對標(biāo)志寄存器產(chǎn)生影響。其他相關(guān)指令通過識別這些被影響的標(biāo)志寄存器位來得知比較結(jié)果。

             

            cmp指令格式:cmp 操作對象1,操作對象2

            功能:計算操作對象1-操作對象2,但并不保存結(jié)果,僅僅根據(jù)計算結(jié)果對標(biāo)志寄存器進行設(shè)置。

             

            比如,指令cmp ax,ax,做(ax)-(ax)的運算,結(jié)果為0,但并不在ax中保存,僅影響flag的相關(guān)各位。指令執(zhí)行后,ZF=1PF=1SF=0CF=0OF=0

            舉例:

            mov ax,8

            mov bx,3

            cmp ax,bx

            執(zhí)行后:(ax)=8ZF=0PF=1SF=0CF=0OF=0

             

            其實,通過cmp指令執(zhí)行后,相關(guān)標(biāo)志位的值就可以看出比較的結(jié)果。

            cmp ax,bx

            如果(ax) = (bx) (ax) – (bx) = 0,所以:ZF = 1

            如果(ax)(bx) (ax) – (bx)0,所以:ZF = 0

            如果(ax)<(bx) (ax) – (bx) 將產(chǎn)生借位,所以:CF=1

            如果(ax)(bx) (ax) – (bx) 將不必借位,所以:CF=0

            如果(ax)>(bx) (ax)-(bx)既不必借位,結(jié)果又不為0,所以:CF=0 并且 ZF=0

            如果(ax)(bx) (ax)-(bx)既可能借位,結(jié)果也可能為0,所以:CF=1 ZF=1

             

            現(xiàn)在我們可以看出比較指令的設(shè)計思路,即:通過做減法運算,影響標(biāo)志寄存器,標(biāo)志寄存器的相關(guān)位記錄了比較的結(jié)果。反過來看上面的例子:

            指令cmp ax,bx的邏輯含義是比較axbx中的值,如果執(zhí)行后:

            ZF=1,說明(ax)=(bx)

            ZF=0,說明(ax)(bx)

            CF=1,說明(ax)<(bx)

            CF=0,說明(ax)(bx)

            CF=0 并且 ZF=0,說明(ax)>(bx)

            CF=1 ZF=1,說明(ax)(bx)

             

            addsub指令一樣,CPU在執(zhí)行cmp指令的時候,也包含兩種含義:進行無符號數(shù)運算和進行有符號數(shù)運算。

             

            所以利用cmp指令可以對無符號數(shù)進行比較,也可以對有符號數(shù)進行比較。

            上面是用cmp進行無符號數(shù)比較時,相關(guān)標(biāo)志位對比較結(jié)果的記錄。

            下面來看一下如果用cmp來進行有符號數(shù)比較時,CPU用哪些標(biāo)志位對比較結(jié)果進行記錄。

            cmp ah,bh

            如果(ah)=(bh) (ah)-(bh)=0,所以ZF=1

            如果(ah)(bh) (ah)-(bh)0,所以ZF=0

             

            對于有符號數(shù)運算,在(ah)<(bh)情況下,(ah)-(bh)顯然可能引起SF=1,即結(jié)果為負。

            比如:

            (ah)=1(bh)=2;則(ah) – (bh)=0FFH0FFH-1的補碼,因為結(jié)果為負,所以SF=1

            (ah)=0FEH(bh)=0FFH;則(ah) – (bh)= – 2 – (–1)=0FFH,因為結(jié)果為負,所以SF=1

             

            (ah)=22H(bh)=0A0H;則(ah) – (bh)=34 – (-96)=82H82H-126的補碼,所以SF=1

             

            兩個有符號婁AB相減,得到的是負數(shù),那么可以肯定A<B,這個思路沒有錯誤,關(guān)鍵在于我們根據(jù)什么來斷定得到的是一個負數(shù)。CPUcmp指令得到的結(jié)果記錄在flag的相關(guān)標(biāo)志位中。我們可以根據(jù)指令執(zhí)行后,相關(guān)標(biāo)志位的值來判斷比較的結(jié)果。單純地考察SF的值不可能知道結(jié)果的正負。因為SF記錄的只是可以在計算機中存放的相應(yīng)位數(shù)的結(jié)果的正負,比如add ah,al執(zhí)行后,SF記錄的是ah中的8位二進制信息所表示的數(shù)據(jù)的正負。cmp ah,bh執(zhí)行后,SF記錄的是(ah)-(bh)所得到的8位二進制信息所表示的數(shù)據(jù)的正負,雖然這個結(jié)果沒有在我們能夠使用的寄存器或內(nèi)存單元中保存,但是在指令執(zhí)行的過程中,它暫存在CPU內(nèi)部的暫存器中。

            所得到的相應(yīng)結(jié)果的正負,并不能說明,運算所應(yīng)該得到的結(jié)果的正負。這是因為在運算的過程中可能發(fā)生溢出。如果有這樣的情況發(fā)生,那么,SF的值就不能說明任何問題。

            比如:

            mov ah,22H

            mov bh,0A0H

            sub ah,bh

            結(jié)果SF=1,運算實際符號得到的結(jié)果是(ah)=82H,但是在邏輯上,運算所應(yīng)該得到的結(jié)果是:34 – (– 96)=130。就是因為130這個結(jié)果作為一個有符號數(shù)超出了-128~127這個范圍,在ah中不能表示,而ah中的結(jié)果被CPU當(dāng)作有符號數(shù)解釋為-126。而SF被用來記錄這個實際結(jié)果的正負,所以SF=1。但SF=1不能說明在邏輯上運算所得的正確結(jié)果的正負。

             

            但是邏輯上的結(jié)果的正負,才是cmp指令所求的真正結(jié)果,因為我們就是要靠它得到兩個操作對象的比較信息。所以cmp指令所作的比較結(jié)果,不是僅僅靠SF就能記錄的,因為它只能記錄實際結(jié)果的正負。

             

            兩種結(jié)果之間的關(guān)系,實際結(jié)果的正負,和邏輯上真正結(jié)果的正負,它們之間有多大的距離呢?

            實際結(jié)果的正負,之所以不能說明邏輯上真正結(jié)果的正負,關(guān)鍵的原因在于發(fā)生了溢出。如果沒有溢出發(fā)生的話,那么,實際結(jié)果的正負和邏輯上真正結(jié)果的正負就一致了。

             

            所以,我們應(yīng)該在考察SF(得知實際結(jié)果的正負)的同時考察OF(得到有沒有溢出),就可以得知邏輯上真正結(jié)果的正負,同時就可以知道比較的結(jié)果。

             

            總結(jié),cmp ah,bh

            1) 如果SF=1,而OF=0

            OF=0,說明沒有溢出,邏輯上真正結(jié)果的正負=實際結(jié)果的正負;

            SF=1,實際結(jié)果為負,所以邏輯上真正的結(jié)果為負,所以(ah)<(bh)

             

            2) 如果SF=1,而OF=1

            OF=1,說明有溢出,邏輯上真正結(jié)果的正負≠實際結(jié)果的正負;

            SF=1,實際結(jié)果為負。

            實際結(jié)果為負,而又有溢出,這說明是由于溢出導(dǎo)致了實際結(jié)果為負,簡單分析一下,就可以看出,如果因溢出導(dǎo)致了實際結(jié)果為負,那么邏輯上真正的結(jié)果必須為正。

            這樣,SF=1OF=1,說明了(ah)>(bh)

             

            3) 如果SF=0,而OF=1

            OF=1,說明有溢出,邏輯上真正結(jié)果的正負≠實際結(jié)果的正負;

            SF=0,實際結(jié)果非負,而OF=1說明有溢出,則結(jié)果非0,所以實際結(jié)果為正。

            實際結(jié)果為正,而又有溢出,這說明是由于溢出導(dǎo)致了實際結(jié)果非負,簡單分析一下,就可以看出,如果因為溢出導(dǎo)致了實際結(jié)果為正,那么邏輯上真正的結(jié)果必須為負

            這樣,SF=0OF=1,說明了(ah)<(bh)

             

            4) 如果SF=0,而OF=0

            OF=0,說明沒有溢出,邏輯上真正結(jié)果的正負=實際結(jié)果的正負;

            SF=0,實際結(jié)果非負,所以邏輯上真正的結(jié)果非負,所以(ah)(bh)

             

            8086CPU這種工作機制的設(shè)計思想,實際上,對于各種處理機來說是普遍的。

             

             

             

            檢測比較結(jié)果的條件轉(zhuǎn)移指令

            “轉(zhuǎn)移”指的是它能夠修改IP,而“條件”指的是它可以根據(jù)某種條件,決定是否修改IP

            比如:jcxz就是一個條件轉(zhuǎn)移指令,它可以檢測cx中的數(shù)值,如果(cx)=0,就修改IP,否則什么也不做。

            所有條件轉(zhuǎn)移指令的轉(zhuǎn)移位移都是[-128~127]

             

            除了jcxz之外,CPU還提供了其他條件轉(zhuǎn)移指令,大多數(shù)條件轉(zhuǎn)移指令都檢測標(biāo)志寄存器的相關(guān)標(biāo)志位,根據(jù)檢測的結(jié)果來決定是否修改IP

            它們檢測的是哪些標(biāo)志位呢?就是被cmp指令影響的那些,表示比較結(jié)果的標(biāo)志位。這些條件轉(zhuǎn)移指令通常都和cmp相配合使用,就好像callret指令通常相配合使用一樣。

             

            因為cmp指令可以同時進行兩種比較,無符號數(shù)比較和有符號數(shù)比較,所以根據(jù)cmp指令的比較結(jié)果進行轉(zhuǎn)移的指令也分為兩種,即:

            根據(jù)無符號數(shù)的比較結(jié)果進行轉(zhuǎn)移的條件轉(zhuǎn)移指令,它們檢測ZFCF的值;

            和根據(jù)有符號數(shù)的比較結(jié)果進行了轉(zhuǎn)移的條件轉(zhuǎn)移指令,它們檢測SFOFZF的值。

             

            常用的根據(jù)無符號數(shù)的比較結(jié)果進行轉(zhuǎn)移的條件轉(zhuǎn)移指令:

            指令

            含義

            檢測的相關(guān)標(biāo)志位

            je

            等于則轉(zhuǎn)移

            ZF=1

            jne

            不等于則轉(zhuǎn)移

            ZF=0

            jb

            低于則轉(zhuǎn)移

            CF=1

            jnb

            不低于則轉(zhuǎn)移

            CF=0

            ja

            高于則轉(zhuǎn)移

            CF=0 ZF=0

            jna

            不高于則轉(zhuǎn)移

            CF=1 ZF=1

             

            j   表示jump             轉(zhuǎn)移

            e 表示equal             等于

            ne:表示not equal        不等于

            b 表示below            小于

            nb:表示not below      不小于

            a 表示above            大于

            na:表示not above       不大于

             

             

            編程實現(xiàn)如下功能:

            如果(ah)=(bh)(ah)=(ah)+(ah),否則(ah)=(ah)+(bh)

            cmp ah,bh

            je s

            add ah,bh

            jmp short ok

            s:add ah,ah

            ok:…

             

            上面的程序執(zhí)行時,如果(ah)=(bh),則cmp ah,bh 使ZF=1,而je檢測ZF是否為1,如果為1,將轉(zhuǎn)移到標(biāo)號s處執(zhí)行指令 add ah,ah。這也可以說,cmp比較ahbh后所得到的相等的結(jié)果使得je指令進行轉(zhuǎn)移。從而很好地體現(xiàn)了je指令的邏輯含義,相等則轉(zhuǎn)移。

             

            雖然je的邏輯含義是“相等則轉(zhuǎn)移”,但它進行的操作是,ZF=1時則轉(zhuǎn)移。

            “相等則轉(zhuǎn)移”這種邏輯含義,是通過和cmp指令配合使用來體現(xiàn)的,因為cmp指令為“ZF=1”賦予了“兩數(shù)相等”的含義。

            至于究竟在je之前使不使用cmp指令,在于我們在安排je檢測的是ZF位置,不管je前面是什么指令,只要CPU執(zhí)行je指令時,ZF=1,那么就會發(fā)生轉(zhuǎn)移。

             

            如何配合使用這些指令,完全取決于程序作者。

             

             

            雖然我們分別討論了cmp指令和與其比較結(jié)果相關(guān)的有條件轉(zhuǎn)移指令,但是它們經(jīng)常在一起配合使用。所以我們在聯(lián)合應(yīng)用它們的時候,不必再考慮cmp指令對相關(guān)標(biāo)志位的影響和je等指令對相關(guān)標(biāo)志位的檢測。因為相關(guān)的標(biāo)志位,只是為cmpje等指令傳遞比較結(jié)果。我們可以直接考慮cmpje等指令配合使用時,表現(xiàn)出來的邏輯含義。它們在聯(lián)合使用的時候表現(xiàn)出來的功能有些像高級語言中的IF語句。

             

             

            上面講解了根據(jù)無符號數(shù)的比較結(jié)果進行轉(zhuǎn)移的條件轉(zhuǎn)移指令。根據(jù)有符號數(shù)的比較結(jié)果進行轉(zhuǎn)移的條件轉(zhuǎn)移指令的工作原理和無符號的相同,只是檢測了不同的標(biāo)志位。

            cmp、標(biāo)志寄存的相關(guān)位、條件轉(zhuǎn)移指令三者配合應(yīng)用,這個原理具有普遍性。

             

             

             

            DF標(biāo)志和串傳送指令

            flag的第10位是DFDirection Flag,方向標(biāo)志位。

            在串處理指令中,控制每操作后sidi的增減。

            DF=0,每次操作后sidi遞增;

            DF=1,每次操作后sidi遞減。

             

            串傳送指令:

            格式:movsb

            功能:執(zhí)行movsb 指令相當(dāng)于進行下面幾步操作:

            1((es)*16+(di)) = ((ds)*16+(si))

            2)如果DF=0則:(si)=(si)+1

                                         (di)=(di)+1

               如果DF=1則:(si)=(si)-1

                                         (di)=(di)-1

            用匯編語法描述movsb的功能如下:

            mov es:[di],byte ptr ds:[si]           ;8086CPU并不支持這樣的指令,這里只是個描述。

            如果DF=0

            inc si

            inc di

            如果DF=1

            dec si

            dec di

             

            movsb指令的功能是將ds:si指向的內(nèi)存單元中的字節(jié)送入es:di中,然后根據(jù)標(biāo)志寄存器DF位的值,將sidi遞增或遞減。

            也可以傳送一個字,指令如下:

            格式:movsw

            movsw的功能是將ds:si指向的內(nèi)存單元中word送入es:di中,然后根據(jù)標(biāo)志寄存器DF位的值,將sidi遞增2或遞減2

            用匯編語法描述movsw的功能如下:

            mov es:[di], word ptr ds:[si]        ;8086CPU并不支持這樣的指令,這里只是個描述。

            如果DF=0

            add si,2

            add di,2

            如果DF=1

            sub si,2

            sub di,2

             

            movsbmovsw進行的是串傳送操作中的一個步驟,一般來說,movsbmovsw都和rep配合使用,格式如下:

            rep movsb

            用匯編語法來描述rep movsb的功能就是:

            s:movsb

            loop s

             

            可見,rep的作用是根據(jù)cx的值,重復(fù)執(zhí)行后面的串傳送指令。

            由于每執(zhí)行一行movsb指令,sidi都會遞增或遞減指向后一個單元或前一個單元,則rep movsb就可以循環(huán)實現(xiàn)(cx)個字符的傳送。

            同理,movsw也有類似功能。

             

            由于flagDF位決定著串傳送指令執(zhí)行后,sidi改變的方向,所以CPU應(yīng)該提供相應(yīng)的指令來對DF位進行設(shè)置,從而使程序員能夠決定傳送的方向。

             

            8086CPU提供下面兩條指令對DF位進行設(shè)置:

            cld指令:將標(biāo)志寄存器的DF位置0

            std指令:將標(biāo)志寄存器的DF位置1

             

            編程:用串傳送指令,將data段中的第一個字符串復(fù)制到它后面的空間中。

            data segment

                   db ‘Welcome to masm!’

                   db 16 dup (0)

            data ends

            分析:使用串傳送指令進行數(shù)據(jù)的傳送,需要給它提供一些必要的信息:

            1) 傳送的原始位置:ds:si

            2) 傳送的目的位置:es:di

            3) 傳送的長度:cx

            4) 傳送的方向:DF

             

            mov ax,data

            mov ds,ax

            mov si,0                ;ds:si指向data:0

            mov es,ax

            mov di,16              ;es:di指向data:16

            mov cx,16             ;(cx)=16, rep循環(huán)16

            cld                        ;設(shè)置DF=0,正向傳送

            rep movsb

             

             

             

            pushfpopf

            pushf的功能是將標(biāo)志寄存器的值壓棧,而popf是從棧中彈出數(shù)據(jù),送入標(biāo)志寄存器中。

             

             

            pushfpopf,為直接訪問標(biāo)志寄存器提供了一種方法。

             

             

            標(biāo)志寄存器在Debug中的表示

            Debug中,標(biāo)志寄存器是按照有意義的各個標(biāo)志位單獨表示的。

             

             

             

             

             

             

             

            posted on 2010-08-04 10:33 luqingfei 閱讀(5167) 評論(0)  編輯 收藏 引用 所屬分類: 匯編語言基礎(chǔ)學(xué)習(xí)

            導(dǎo)航

            <2025年6月>
            25262728293031
            1234567
            891011121314
            15161718192021
            22232425262728
            293012345

            統(tǒng)計

            留言簿(6)

            隨筆分類(109)

            隨筆檔案(105)

            Blogers

            Game

            Life

            NodeJs

            Python

            Useful Webs

            大牛

            搜索

            積分與排名

            最新評論

            閱讀排行榜

            評論排行榜

            久久精品人人做人人爽电影| 国产激情久久久久影院| 亚洲av伊人久久综合密臀性色| 精品久久人人爽天天玩人人妻| 精品久久8x国产免费观看| 久久久久久a亚洲欧洲aⅴ| 久久国产影院| 国产∨亚洲V天堂无码久久久| 久久综合亚洲鲁鲁五月天| 久久99热这里只有精品国产| 久久国产热这里只有精品| 少妇久久久久久被弄到高潮 | 亚洲国产精品成人久久蜜臀 | 久久妇女高潮几次MBA| 国产成人无码精品久久久性色| 久久午夜福利无码1000合集| 午夜天堂av天堂久久久| 国产亚洲成人久久| 久久人人爽人人爽人人片AV东京热| AAA级久久久精品无码区| 久久久午夜精品| 午夜精品久久久久久久久| 欧美伊人久久大香线蕉综合69 | 国产三级观看久久| 久久婷婷五月综合色奶水99啪 | 久久人妻少妇嫩草AV蜜桃| 亚洲国产精品无码久久SM| 欧美日韩精品久久久免费观看| 免费国产99久久久香蕉| 久久久久亚洲AV无码永不| 久久99国产一区二区三区| 99久久夜色精品国产网站| 国内精品久久久久久久涩爱| 一本久道久久综合狠狠躁AV| 久久久不卡国产精品一区二区| 久久久精品免费国产四虎| 亚洲一区二区三区日本久久九| 日本福利片国产午夜久久| 久久精品中文字幕大胸| 91精品国产综合久久婷婷| 国产V综合V亚洲欧美久久|