日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

X86匯編學(xué)習(xí)小結(jié)

 herowuking 2015-09-26

生成匯編代碼


比如,一個(gè)簡(jiǎn)單的函數(shù):

// hello.c
void func(){}

如何得到相應(yīng)的匯編代碼呢?

gcc -S hello.c

hello.s

clang -S hello.c

hello.s

gcc -S -masm=intel hello.c

hello.s

cl /FAs /C hello.c

hello.asm

看些結(jié)果:

  • gcc 4.5.2, Ubuntu11.04 X86 默認(rèn)的匯編

.globl func
        .type   func, @function
func:
        pushl   %ebp
        movl    %esp, %ebp
        popl    %ebp
        ret
  • clang 2.8, Ubuntu11.04 X86

    .globl  func
    .align  16, 0x90
    .type   func,@function
func:
    pushl   %ebp
    movl    %esp, %ebp
    popl    %ebp
    ret
.Ltmp0:
    .size   func, .Ltmp0-func
  • gcc 4.5.2, Ubuntu11.04 X86 Intel格式的匯編

.globl func
        .type   func, @function
func:
        push    ebp
        mov     ebp, esp
        pop     ebp
        ret
  • cl 16 (即VC10), Windows Xp

_func   PROC
; 1    : void func(){}
        push    ebp
        mov     ebp, esp
        pop     ebp
        ret     0
_func   ENDP
  • 順便看一個(gè)Sun Studio 11: C 5.8 compiler,SPARC架構(gòu)(服務(wù)器來(lái)自u(píng)nix-center)

        .global func
        .type   func,#function
func:
        save    %sp,-96,%sp
        jmp     %i7+8
        restore
...
  • 以及GCC 4.0.1,SPARC架構(gòu)(服務(wù)器來(lái)自u(píng)nix-center)

        .global func
func:   
        retl    ! Result = 
        nop
        .type   func,2
        .size   func,(.-func)
...

這些東西太復(fù)雜了,關(guān)注點(diǎn)只能限制到X86架構(gòu)了。先看一下X86下常用的兩種匯編有哪些不同。

X86匯編語(yǔ)言 差異

X86 下常用的匯編有 AT&T 與 Intel 兩種(fix me?),二者在語(yǔ)法上有一定的差異:

  • 注:本節(jié)內(nèi)容來(lái)自http://,文字和格式進(jìn)行了重新整理。

前綴/后綴

區(qū)別:

 

Intel語(yǔ)法

AT&T語(yǔ)法

寄存器

 

加前綴 %

立即數(shù)

   

加前綴 $

十六進(jìn)制

加后綴h

數(shù)字前加 0x

二進(jìn)制

加后綴b

 

例子:

Intel語(yǔ)法

AT&T語(yǔ)法

mov eax,8

movl $8,%eax

mov ebx,0ffffh

movl $0xffff,%ebx

int 80h

int $0x80

操作數(shù)的方向

  • 二者方向正好相反
  • Intel語(yǔ)法,第一個(gè)是目的操作數(shù),第二個(gè)是源操作數(shù)。
  • AT&T中,第一個(gè)數(shù)是源操作數(shù),第二個(gè)數(shù)是目的操作數(shù)。(更符合閱讀習(xí)慣哈)

例子:

Intel語(yǔ)法(<==)

AT&T語(yǔ)法(==>)

mov eax,[ecx]

movl (%ecx),%eax

內(nèi)存單元操作數(shù)

  • 在Intel的語(yǔ)法中,基寄存器用“[]”括起來(lái)
  • 而在AT&T中,用“()”括起來(lái)。

Intel

AT&T

mov eax,[ebx+5]

movl 5(%ebx),%eax

間接尋址方式

  • Intel的指令格式是segreg:[base+index*scale+disp]

  • AT&T的格式是%segreg:disp(base,index,scale)

Intel語(yǔ)法

AT&T語(yǔ)法

指令 foo,segreg:[base+index*scale+disp]

指令 %segreg:disp(base,index,scale),foo

mov eax,[ebx+20h]

Movl 0x20(%ebx),%eax

add eax,[ebx+ecx*2h]

Addl (%ebx,%ecx,0x2),%eax

lea eax,[ebx+ecx]

Leal (%ebx,%ecx),%eax

sub eax,[ebx+ecx*4h-20h]

Subl -0x20(%ebx,%ecx,0x4),%eax

操作碼的后綴

  • 在AT&T的操作碼后加后綴,“l(fā)”(long,32位),“w”(word,16位),“b”(byte,8位)

  • 在Intel的語(yǔ)法中,在操作數(shù)的前加byte ptr、 word ptr 或 dword ptr

例子:

Intel語(yǔ)法

AT&T語(yǔ)法

Mov al,bl

movb %bl,%al

Mov ax,bx

movw %bx,%ax

Mov eax,ebx

movl %ebx,%eax

Mov eax, dword ptr [ebx]

movl (%ebx),%eax

找個(gè)例子看看

  • hello.c

int func(int i)
{
    return 2 * i;
}

int main()
{
    int s = func(255);
    return 0;
}
  • hello.s (gcc4.5.2, x86/ubuntu11.04)

func:

 

    pushl   %ebp

將ebp內(nèi)容壓棧保存

    movl    %esp, %ebp

 

    movl    8(%ebp), %eax

注意到立即數(shù)255在main中壓棧后,先后有IP和本函數(shù)內(nèi)的ebp壓棧,故,棧頂+8指向立即數(shù)255

    addl    %eax, %eax

乘法操作變成了加法,eax存放返回值

    popl    %ebp

ebp出棧

    ret

函數(shù)返回,(IP出棧)

main:

 

    pushl   %ebp

將ebp內(nèi)容壓棧保存,

    movl    %esp, %ebp

將棧頂保存到ebp中

    subl    $20, %esp

棧頂下移20字節(jié),用來(lái)保存局部變量

    movl    $255, (%esp)

將立即數(shù)255放入棧頂所指位置

    call    func

調(diào)用函數(shù)func,(此時(shí)將下條指令地址IP壓入棧中)

    movl    %eax, -4(%ebp)

將func的返回值放入局部變量中(-4(%ebp)就是變量s的位置)

    movl    $0, %eax

0送入eax,準(zhǔn)備返回值

    leave

leave等價(jià)于 movl %ebp,%esp 和 popl %ebp

    ret

 

參考

  • http:///kernel-book/ch02/2.6.1.htm

  • http://bbs./thread-106533-1-1.html

    ==================================================================================================


    X86 匯編語(yǔ)言中CPU上的通用寄存器簡(jiǎn)要說(shuō)明 

      eax, ebx, ecx, edx, esi, edi, ebp, esp等都是X86 匯編語(yǔ)言中CPU上的通用寄存器的名稱(chēng),是32位的寄存器。如果用C語(yǔ)言來(lái)解釋?zhuān)梢园堰@些寄存器當(dāng)作變量看待。

      比方說(shuō):add eax,-2 ;   //可以認(rèn)為是給變量eax加上-2這樣的一個(gè)值。

      這些32位寄存器有多種用途,但每一個(gè)都有“專(zhuān)長(zhǎng)”,有各自的特別之處。

      EAX 是"累加器"(accumulator), 它是很多加法乘法指令的缺省寄存器。

      EBX 是"基地址"(base)寄存器, 在內(nèi)存尋址時(shí)存放基地址。

      ECX 是計(jì)數(shù)器(counter), 是重復(fù)(REP)前綴指令和LOOP指令的內(nèi)定計(jì)數(shù)器。

      EDX 則總是被用來(lái)放整數(shù)除法產(chǎn)生的余數(shù)。

      ESI/EDI 分別叫做"源/目標(biāo)索引寄存器"(source/destination index),因?yàn)樵诤芏嘧址僮髦噶钪? DS:ESI指向源串,而ES:EDI指向目標(biāo)串.

      EBP 是"基址指針"(BASE POINTER), 它最經(jīng)常被用作高級(jí)語(yǔ)言函數(shù)調(diào)用的"框架指針"(frame pointer). 在破解的時(shí)候,經(jīng)??梢钥匆?jiàn)一個(gè)標(biāo)準(zhǔn)的函數(shù)起始代碼:

      push ebp ; 保存當(dāng)前ebp
      mov ebp,esp ; EBP設(shè)為當(dāng)前堆棧指針
      sub esp, xxx ; 預(yù)留xxx字節(jié)給函數(shù)臨時(shí)變量.
      ...

      這樣一來(lái),EBP 構(gòu)成了該函數(shù)的一個(gè)框架, 在EBP上方分別是原來(lái)的EBP, 返回地址和參數(shù). EBP下方則是臨時(shí)變量. 函數(shù)返回時(shí)作 mov esp,ebp/pop ebp/ret 即可.

      ESP 專(zhuān)門(mén)用作堆棧指針,被形象地稱(chēng)為棧頂指針,堆棧的頂部是地址小的區(qū)域,壓入堆棧的數(shù)據(jù)越多,ESP也就越來(lái)越小。 在32位平臺(tái)上,ESP每次減少4字節(jié)。

      esp:寄存器存放當(dāng)前線程的棧頂指針
      ebp:寄存器存放當(dāng)前線程的棧底指針
      eip:寄存器存放下一個(gè)CPU指令存放的內(nèi)存地址,當(dāng)CPU執(zhí)行完當(dāng)前的指令后,從EIP寄存器中讀取下一條指令的內(nèi)存地址,然后繼續(xù)執(zhí)行。

      一般寄存器:AX、BX、CX、DX
      AX:累積暫存器,BX:基底暫存器,CX:計(jì)數(shù)暫存器,DX:資料暫存器

      索引暫存器:SI、DI 
      SI:來(lái)源索引暫存器,DI:目的索引暫存器 

      堆疊、基底暫存器:SP、BP 
      SP:堆疊指標(biāo)暫存器,BP:基底指標(biāo)暫存器 

      EAX、ECX、EDX、EBX:為ax,bx,cx,dx的延伸,各為32位元 
      ESI、EDI、ESP、EBP:為si,di,sp,bp的延伸,32位元

      棧的基本模型

       

      參數(shù)N

      ↓高地址

      參數(shù)…

      函數(shù)參數(shù)入棧的順序與具體的調(diào)用方式有關(guān)

      參數(shù) 3

      參數(shù) 2

      參數(shù) 1

      EIP

      返回本次調(diào)用后,下一條指令的地址

      EBP

      保存調(diào)用者的EBP,然后EBP指向此時(shí)的棧頂。

      臨時(shí)變量1

       

      臨時(shí)變量2

       

      臨時(shí)變量3

       

      臨時(shí)變量…

       

      臨時(shí)變量5

      ↓低地址

  • ===========================================================================
  • 80x86指令系統(tǒng)


      80x86指令系統(tǒng),指令按功能可分為以下七個(gè)部分。
      (1) 數(shù)據(jù)傳送指令。
      (2) 算術(shù)運(yùn)算指令。
      (3) 邏輯運(yùn)算指令。
      (4) 串操作指令。
      (5) 控制轉(zhuǎn)移指令。
      (6) 處理器控制指令。
      (7) 保護(hù)方式指令。
      3.3.1數(shù)據(jù)傳送指令
      數(shù)據(jù)傳送指令包括:通用數(shù)據(jù)傳送指令、地址傳送指令、標(biāo)志寄存器傳送指令、符號(hào)擴(kuò)展指令、擴(kuò)展傳送指令等。
      一、通用數(shù)據(jù)傳送指令
      1傳送指令
      傳送指令是使用最頻繁的指令,格式:MOV DEST,SRC
      功能:把一個(gè)字節(jié),字或雙字從源操作數(shù)SRC傳送至目的操作數(shù)DEST。
      傳送指令允許的數(shù)據(jù)流方向見(jiàn)圖311。

    圖 3.11  傳送指令數(shù)據(jù)流

      由上圖可知,數(shù)據(jù)允許流動(dòng)方向?yàn)椋和ㄓ眉拇嫫髦g、通用寄存器和存儲(chǔ)器之間、通用寄存器和段寄存器之間、段寄存器和存儲(chǔ)器之間,另外還允許立即數(shù)傳送至通用寄存器或存儲(chǔ)器。但在上述傳送過(guò)程中,段寄存器CS的值不能用傳送指令改變。
      例 3.12CPU內(nèi)部寄存器之間的數(shù)據(jù)傳送。
      MOV AL,DH    ;AL←DH    (8位)
      MOV DS,AX   ??;DS←AX    (16位)
      MOV EAX,ESI  ?。籈AX←ESI   (32位)
      例 3.13CPU內(nèi)部寄存器和存儲(chǔ)器之間的數(shù)據(jù)傳送。
      MOV [BX],AX       ;間接尋址     (16位)
      MOV EAX,[EBX+ESI]  ??;基址變址尋址   (32位)
      MOV AL,BLOCK      ;BLOCK為變量名,直接尋址(8位)
    例 3.14立即數(shù)送通用寄存器、存儲(chǔ)器。
      MOV EAX,12345678H  ??;EAX←12345678H   (32位)
      MOV [BX],12H      ;間接尋址      (8位)
      MOV AX,1234H;AX←1234H(16位)
      使用該指令應(yīng)注意以下問(wèn)題:
      ·源和目的操作數(shù)不允許同時(shí)為存儲(chǔ)器操作數(shù);
      ·源和目的操作數(shù)數(shù)據(jù)類(lèi)型必須一致;
      ·源和目的操作數(shù)不允許同時(shí)為段寄存器;
      ·目的操作數(shù)不允許為CS和立即數(shù);
      ·當(dāng)源操作數(shù)為立即數(shù)時(shí),目的操作數(shù)不允許為段寄存器;
      ·傳送操作不影響標(biāo)志位。
      2擴(kuò)展傳送指令
      格式:MOV SX DEST,SRC
         MOV ZX DEST,SRC
      功能:將源操作數(shù)由8位擴(kuò)展到16位送目的操作數(shù),或由16位擴(kuò)展到32位送目的操作數(shù)。其中MOVSX是按有符號(hào)數(shù)擴(kuò)展,MOVZX是按無(wú)符號(hào)數(shù)擴(kuò)展。無(wú)符號(hào)數(shù)或正數(shù)高位擴(kuò)展為0,負(fù)數(shù)高位擴(kuò)展為全“1”。
      例 3.15帶符號(hào)數(shù)擴(kuò)展
      MOV BL,80H ??; -128
      MOVSX AX,BL ??; 將80H擴(kuò)展為FF80H后送AX中。
      例 3.16無(wú)符號(hào)數(shù)擴(kuò)展
      MOV BL,80H  ; 128
      MOVZX AX,BL ?。弧?0H擴(kuò)展為0080H后送AX中。
      使用該指令應(yīng)注意以下問(wèn)題:
      ·目的操作數(shù)應(yīng)為16位或32位通用寄存器;
      ·源操作數(shù)長(zhǎng)度須小于目的操作數(shù)長(zhǎng)度,為8位或16位通用寄存器或存儲(chǔ)器操作數(shù);
      ·擴(kuò)展傳送操作不影響標(biāo)志位。
      3交換指令
      (1) 格式:XCHG OPR1,OPR2
      功能:交換操作數(shù)OPR1和OPR2的值,操作數(shù)數(shù)據(jù)類(lèi)型為字節(jié)、字或雙字。允許通用寄存器之間,通用寄存器和存儲(chǔ)器之間交換數(shù)據(jù)。
      例 3.17
      XCHG AX,BX;通用寄存器之間交換數(shù)據(jù)(16位)
      XCHG ESI,EDI;通用寄存器之間交換數(shù)據(jù)(32位)
      XCHG BX,/[SI/];通用寄存器和存儲(chǔ)器之間交換數(shù)據(jù)(16位)
      XCHG AL,/[BX/];通用寄存器和存儲(chǔ)器之間交換數(shù)據(jù)(8位)
      使用該指令應(yīng)注意以下問(wèn)題:
      ·操作數(shù)OPR1和OPR2不允許同為存儲(chǔ)器操作數(shù);
      ·操作數(shù)數(shù)據(jù)類(lèi)型必須一致;
      ·交換指令不影響標(biāo)志位。
      如要實(shí)現(xiàn)存儲(chǔ)器操作數(shù)交換,可用如下指令實(shí)現(xiàn):
                   MOV AL,BLOCK1
                   XCHG AL,BLOCK2
                   MOV BLOCK1,AL
      (2) 格式:BSWAP REG
      功能:將32位通用寄存器中,第1個(gè)字節(jié)和第4個(gè)字節(jié)交換,第2個(gè)字節(jié)和第3個(gè)字節(jié)交換。
    例 3.18
      MOV EAX,44332211H
      BSWAP EAX;EAX=11223344H
      使用該指令應(yīng)注意以下問(wèn)題:
      ·操作數(shù)為32位通用寄存器;
      ·交換指令不影響標(biāo)志位。
      二、堆棧操作指令
      1壓棧指令
      (1) 格式:PUSH SRC
      功能:將源操作數(shù)壓下堆棧,源操作數(shù)允許為16位或32位通用寄存器、存儲(chǔ)器和立即數(shù)以及16位段寄存器。當(dāng)操作數(shù)數(shù)據(jù)類(lèi)型為字類(lèi)型,壓棧操作使SP值減2;當(dāng)數(shù)據(jù)類(lèi)型為雙字類(lèi)型,壓棧操作使SP值減4。
      例 3.19
      PUSH AX          ;通用寄存器操作數(shù)入棧(16位)
      PUSH EBX          ;通用寄存器操作數(shù)入棧(32位)
      PUSH [SI]         ;存儲(chǔ)器操作數(shù)入棧(16位)
      PUSH DWORD PTR [DI]   ?。淮鎯?chǔ)器操作數(shù)入棧(32位)
      PUSHW 0A123H        ;立即數(shù)入棧(16位)
      PUSHD 20H         ;立即數(shù)入棧(32位)
      (2) 格式:PUSHA
           PUSHAD
      功能:PUSHA將16位通用寄存器壓入堆棧,壓棧順序?yàn)锳X,CX,DX,BX,SP,BP,SI,DI。
    PUSHAD將32位通用寄存器壓入堆棧,壓棧順序?yàn)镋AX,ECX,EDX,EBX,ESP,EBP,ESI,EDI。
      2出棧指令
      (1) 格式:POP DEST
      功能:從棧頂彈出操作數(shù)送入目的操作數(shù)。目的操作數(shù)允許為16或32位通用寄存器、存儲(chǔ)器和16位段寄存器。當(dāng)操作數(shù)數(shù)據(jù)類(lèi)型為字類(lèi)型,出棧操作使SP加2;當(dāng)操作數(shù)數(shù)據(jù)類(lèi)型為雙字類(lèi)型,出棧操作使SP加4。
      例 3.20
      POP AX          ;操作數(shù)出棧送寄存器(16位)
      POP ECX          ;操作數(shù)出棧送寄存器(32位)
      POP [BX]        ??;操作數(shù)出棧送存儲(chǔ)器(16位)
      POP DWORD PTR [SI]    ;操作數(shù)出棧送存儲(chǔ)器(32位)
      (2) 格式:POPA
           POPAD
      功能:POPA從堆棧移出16字節(jié)數(shù)據(jù),并且按順序存入寄存器DI,SI,BP,SP,BX,DX,CX,AX中。
      POPAD從堆棧移出32字節(jié)數(shù)據(jù),并且按順序存入寄存器EDI,ESI,EBP,ESP,EBX,EDX,ECX,EAX中。
      使用堆棧操作指令應(yīng)注意以下問(wèn)題。
      (1) 目的操作數(shù)不允許為CS以及立即數(shù)。
      (2) 堆棧操作指令不影響標(biāo)志位。
      三、地址傳送指令
      (1) 格式:LEA REG,MEM
      功能:將源操作數(shù)的有效地址傳送到通用寄存器,操作數(shù)REG為16位或32位通用寄存器,源操作數(shù)為16位或32位存儲(chǔ)器操作數(shù)。
      例 3.21
      LEA BX,BLOCK;將BLOCK的有效地址傳送到BX中(16位)
      LEA EAX,/[EBX/];將EBX內(nèi)容(有效地址)傳送到EAX中(32位)
      (2) 格式LDS(ES,F(xiàn)S,GS,SS)REG,MEM
      功能:根據(jù)源操作數(shù)指定的偏移地址,在數(shù)據(jù)段中取出段地址和偏移地址分別送指定的段寄存器和指定的通用寄存器。
      例 3.22
      LES BX,[SI]        ;將32位地址指針?lè)謩e送ES和BX
      LSS EAX,[EDI]      ?。粚?8位地址指針?lè)謩e送SS和EAX
       
      例 3.23
      DATA1  DD buff
       
      LDS BX,DATA1;將buff的32位地址指針?lè)謩e送DS和BX
       
    地址傳送指令對(duì)標(biāo)志位無(wú)影響。
      四、標(biāo)志寄存器傳送指令
      (1) 格式:LAHF
           SAHF
      功能:LAHF將標(biāo)志寄存器中低8位送AH中。SAHF將AH中內(nèi)容送標(biāo)志寄存器中低8位。
      (2) 格式:PUSHF
           POPF
      功能:PUSHF將標(biāo)志寄存器低16位內(nèi)容壓入堆棧,SP←SP-2。POPF將當(dāng)前棧頂一個(gè)字傳送到標(biāo)志寄存器低16位中,SP←SP+2。
      (3) 格式:PUSHFD
           POPFD
      功能:PUSHFD將標(biāo)志寄存器32位內(nèi)容壓入堆棧SP←SP-4。POPFD將當(dāng)前棧頂一個(gè)雙字傳送到32位標(biāo)志寄存器中,SP←SP+4。
      上述SAHF,POPF,POPFD均影響相應(yīng)的標(biāo)志寄存器內(nèi)容。
      五、查表指令
      格式:XLAT
      功能:將寄存器AL中的內(nèi)容轉(zhuǎn)換成存儲(chǔ)器表格中的對(duì)應(yīng)值。實(shí)現(xiàn)直接查表功能。
      XLAT指令規(guī)定:BX寄存器存放表的首地址,AL寄存器中存放表內(nèi)偏移量,執(zhí)行XLAT指令,以段寄存器DS的內(nèi)容為段基址,有效地址為BX和AL內(nèi)容之和,取出表中一個(gè)字節(jié)內(nèi)容送AL中。
      例 3.24內(nèi)存中有一起始地址為T(mén)ABLE的編碼表,試編程將表中順序號(hào)為4的存儲(chǔ)單元內(nèi)容送寄存器AL。
             ·MODEL SMALL
             ·DATA
      TABLE      DB 11H,22H,33H,44H,55H 某編碼表
             ·CODE
             ·STARTUP
              MOV AL,4           ;AL←4
              MOV BX,OFFSET TABLE    ??;BX←TABLE表首地址
              XLAT            ??;結(jié)果在AL中,AL=55H
             ·EXIT
              END
      查表指令不影響標(biāo)志位。
      六、符號(hào)擴(kuò)展指令
      (1) 格式:CBW
      功能:將AL中8位帶符號(hào)數(shù),進(jìn)行帶符號(hào)擴(kuò)展為16位,送AX中。帶符號(hào)擴(kuò)展是指對(duì)正數(shù)高位擴(kuò)展為全“0”,對(duì)負(fù)數(shù)高位擴(kuò)展為全“1”。
      例 3.25AL=55H 經(jīng)CBW擴(kuò)展后 AX=0055H
          AL=A5H 經(jīng)CBW擴(kuò)展后 AX=FFA5H
      (2) 格式:CWD
      功能:將AX中16位帶符號(hào)數(shù),進(jìn)行帶符號(hào)擴(kuò)展為32位,送DX和AX中。高16位送DX中,低16位送AX中。
      (3) 格式:CWDE
      功能:將AX中16位帶符號(hào)數(shù),進(jìn)行帶符號(hào)擴(kuò)展為32位,送EAX中。
      (4) 格式:CDQ
      功能:將EAX中32位帶符號(hào)數(shù),進(jìn)行帶符號(hào)擴(kuò)展為64位,送EDX和EAX中。低32位送EAX中,高32位送EDX中。
      符號(hào)擴(kuò)展指令對(duì)標(biāo)志位無(wú)影響。
      3.3.2 算術(shù)運(yùn)算指令
      80x86指令包括加、減、乘、除四種基本算術(shù)運(yùn)算操作及十進(jìn)制算術(shù)運(yùn)算調(diào)整指令。二進(jìn)制加、減法指令,帶符號(hào)操作數(shù)采用補(bǔ)碼表示時(shí),無(wú)符號(hào)數(shù)和帶符號(hào)數(shù)據(jù)運(yùn)算可以使用相同的指令。二進(jìn)制乘、除法指令分帶符號(hào)數(shù)和無(wú)符號(hào)數(shù)運(yùn)算指令。
      一、加法指令
      格式:ADDDEST,SRC
         ADCDEST,SRC
      功能:ADD是將源操作數(shù)與目的操作數(shù)相加,結(jié)果傳送到目的操作數(shù)。ADC是將源操作數(shù)與目的操作數(shù)以及CF(低位進(jìn)位)值相加,結(jié)果傳送到目的操作數(shù)。
      源操作數(shù)可以是通用寄存器、存儲(chǔ)器或立即數(shù)。目的操作數(shù)可以是通用寄存器或存儲(chǔ)器操作數(shù)。
    ADD,ADC指令影響標(biāo)志位為OF,SF,ZF,AF,PF,CF。
      例 3.26
      MOV AX,9876H
      ADD AH,AL;AX=0E76H CF=1 SF=0O F=0 ZF=0 AF=0 PF=0
      ADC AH,AL;AX=8576H CF=0 SF=1O F=1 ZF=0 AF=1 PF=0
      二、減法指令
      格式:SUB DEST,SRC
         SBB DEST,SRC
      功能:SUB將目的操作數(shù)減源操作數(shù),結(jié)果送目的操作數(shù)。SBB將目的操作數(shù)減源操作數(shù),還要減CF(低位借位)值,結(jié)果送目的操作數(shù)。
      源操作數(shù)可以是通用寄存器、存儲(chǔ)器或立即數(shù)。目的操作數(shù)可以是通用寄存器或存儲(chǔ)器操作數(shù)。
    SUB,SBB指令影響標(biāo)志位為OF,SF,ZF,AF,PF,CF。
      例 3.27
      MOV AX, 9966H;AX=9966H
      SUB AL, 80H;AL=E6HCF=1SF=1OF=1ZF=0AF=0PF=0
      SBB AH, 80H;AH=18HCF=0SF=0OF=0ZF=0AF=0PF=1
      三、加1減1指令
      格式:INC DEST
         DEC DEST
      功能:INC指令將目的操作數(shù)加1,結(jié)果送目的操作數(shù)。DEC指令將目的操作數(shù)減1,結(jié)果送目的操作數(shù)。目的操作數(shù)為通用寄存器或存儲(chǔ)器操作數(shù)。
      INC,DEC指令影響標(biāo)志位為OF,SF,ZF,AF,PF。
      例 3.28
      INC BL;BL←BL+1
      INC AX;AX←AX+1
      INC WORDPTR [BX];存儲(chǔ)器操作數(shù)加1
      DEC BYTE PTR [SI];存儲(chǔ)器操作數(shù)減1
      DEC EAX;EAX←EAX-1
      四、比較指令
      (1) 格式:CMP DEST,SRC =============這個(gè)是intel格式
      功能:目的操作數(shù)減源操作數(shù),結(jié)果不回送。源操作數(shù)為通用寄存器、存儲(chǔ)器和立即數(shù)。目的操作數(shù)為通用寄存器、存儲(chǔ)器操作數(shù)。
      CMP指令影響標(biāo)志位為OF,SF,ZF,AF,PF,CF。

      例 3.29
      CMP CX,3
      CMP WORD PTR [SI],3
      CMP AX,BLOCK
      執(zhí)行比較指令后,對(duì)狀態(tài)標(biāo)志位影響見(jiàn)表3.2。對(duì)于兩個(gè)數(shù)的比較(AX-BX)有以下3種情況。

    表 3.2 CMP指令對(duì)標(biāo)志位的影響


      · 兩個(gè)正數(shù)比較,使用SF標(biāo)志位判斷。
        SF=0,則AX≥BX,若ZF=1,則AX=BX
        SF=1,則AX<BX
      · 兩個(gè)無(wú)符號(hào)數(shù)比較,使用CF標(biāo)志位判斷。
        CF=0,則AX≥BX,若ZF=1,則AX=BX
        CF=1,則AX<BX
      · 兩個(gè)負(fù)數(shù)比較,使用SF標(biāo)志位判斷。
        SF=0,則AX≥BX,若ZF=1,則AX=BX
        SF=1,則AX<BX
      · 兩個(gè)異符號(hào)數(shù)比較。
        如果OF=0,仍可用SF標(biāo)志判斷大小。
        如果OF=1,說(shuō)明結(jié)果的符號(hào)位發(fā)生錯(cuò)誤,所以
             SF=0,則AX<BX
             SF=1,則AX>BX
      綜上所述:兩個(gè)異號(hào)數(shù)比較
      當(dāng)OF=0,SF=0,則AX>BX
          SF=1,則AX<BX
      當(dāng)OF=1,SF=0,則AX<BX
          SF=1,則AX>BX
      用邏輯表達(dá)式表示為:
      若OF∨-SF=0,則AX>BX
      若OF∨-SF=1,則AX<BX
      (2) 格式:CMPXCHGDEST,REG
      功能:目的操作數(shù)減源操作數(shù),
        如果DEST=SRC,則SRC→DEST。
        如果DEST≠SRC,則DEST→ACC(AL,AX,EAX)。
      源操作數(shù)允許為通用寄存器。目的操作數(shù)可以為通用寄存器,存儲(chǔ)器操作數(shù)。
      CMPXCHG影響標(biāo)志位為OF,SF,ZF,AF,PF,CF。
      (3) 格式:CMPXCHG8BMEM
      功能:EDX:EAX中值減存儲(chǔ)器操作數(shù)。
        如果EDX:EAX=MEM64,則ECX:EBX→MEM64。
        如果EDX:EAX≠M(fèi)EM64,則MEM64→EDX:EAX。
      該指令為64位比較交換指令,影響ZF標(biāo)志位。
      例 3.30  CMPXCHG8BQWORDPTR[EBX]
      五、交換相加指令
      格式:XADDDEST,REG
      功能:目的操作數(shù)加源操作數(shù),結(jié)果送目的操作數(shù)。原目的操作數(shù)內(nèi)容送源操作數(shù)。源操作數(shù)允許為通用寄存器。目的操作數(shù)允許為通用寄存器、存儲(chǔ)器操作數(shù)。
      XADD指令影響標(biāo)志位為OF,SF,ZF,AF,PF,CF。
      六、求補(bǔ)指令
      格式:NEGDEST
      功能:對(duì)目的操作數(shù)求補(bǔ),用零減去目的操作數(shù),結(jié)果送目的操作數(shù)。目的操作數(shù)為通用寄存器、存儲(chǔ)器操作數(shù)。
      NEG指令影響標(biāo)志位為OF,SF,ZF,AF,PF,CF。
      七、乘法指令
      (1) 格式:MULSRC
           IMULSRC
      功能:MUL為無(wú)符號(hào)數(shù)乘法指令,IMUL為帶符號(hào)數(shù)乘法指令。源操作數(shù)為通用寄存器或存儲(chǔ)器操作數(shù)。目的操作數(shù)缺省存放在ACC(AL,AX,EAX)中,乘積存AX,DX:AX,EDX:EAX中。
      字節(jié)乘:ALSRC→AX
      字乘:AXSRC→DX∶AX
      雙字乘:EAXSRC→EDX∶EAX
      MUL,IMUL指令執(zhí)行后,CF=OF=0,表示乘積高位無(wú)有效數(shù)據(jù);CF=OF=1表示乘積高位含有效數(shù)據(jù),對(duì)其它標(biāo)志位無(wú)定義。
      例 3.31
      MUL BL;字節(jié)乘
      MUL WORD PTR [SI];字乘
      IMUL BYTE PTR [DI];字節(jié)乘
      IMUL DWORD PTR [ECX];雙字乘
      如果使用IMUL指令,積采用補(bǔ)碼形式表示。
      (2) 格式:IMULDEST,SRC
      功能:將目的操作數(shù)乘以源操作數(shù),結(jié)果送目的操作數(shù)。目的操作數(shù)為16位或32位通用寄存器或存儲(chǔ)器操作數(shù)。源操作數(shù)為16位或32位通用寄存器、存儲(chǔ)器或立即數(shù)。
      源操作數(shù)和目的操作數(shù)數(shù)據(jù)類(lèi)型要求一致。乘積僅取和目的操作數(shù)相同的位數(shù),高位部分將被舍去,并且CF=OF=1。其它標(biāo)志位無(wú)定義。
      (3) 格式:IMUL DEST,SRC1,SRC2
      功能:將源操作數(shù)SRC1與源操作數(shù)SRC2相乘,結(jié)果送目的操作數(shù)。目的操作數(shù)DEST為16位或32位,允許為通用寄存器。源操作數(shù)SRC1為16位或32位通用寄存器或存儲(chǔ)器操作數(shù)。源操作數(shù)SRC2允許為立即數(shù)。
      例 3.32  IMULEAX,[EBX],12H
      要求目的操作數(shù)和源操作數(shù)SRC1類(lèi)型相同,當(dāng)乘積超出目的操作數(shù)部分,將被舍去,并且使CF=OF=1,在使用這類(lèi)指令時(shí),需在IMUL指令后加一條判斷溢出的指令,溢出時(shí)轉(zhuǎn)錯(cuò)誤處理執(zhí)行程序。
      八、除法指令
      格式:DIV SRC
         IDIV SRC
      功能:DIV為無(wú)符號(hào)數(shù)除法,IDIV為帶符號(hào)數(shù)除法。源操作數(shù)作為除數(shù),為通用寄存器或存儲(chǔ)器操作數(shù)。被除數(shù)缺省在目的操作數(shù)AX,DX:AX,EDX:EAX中。
      字節(jié)除法:AX/SRC商→AL,余數(shù)→AH
      字除法:DX·AX/SRC商→AX,余數(shù)→DX
      雙字除法:EDX·EAX/SRC商→EAX,余數(shù)→EDX
      由于被除數(shù)必須是除數(shù)的雙倍字長(zhǎng),一般應(yīng)使用擴(kuò)展指令進(jìn)行高位擴(kuò)展。當(dāng)進(jìn)行無(wú)符號(hào)數(shù)除法時(shí),被除數(shù)高位按0擴(kuò)展為雙倍除數(shù)字長(zhǎng)。當(dāng)進(jìn)行有符號(hào)數(shù)除法時(shí),被除數(shù)以補(bǔ)碼表示??墒褂脭U(kuò)展指令CBW,CWD,CWDE,CDQ進(jìn)行高位擴(kuò)展。例如:
      MOV AX,BLOCK
      CWD;被除數(shù)高位擴(kuò)展
      MOV BX,1000H
      IDIV BX
      對(duì)于帶符號(hào)除法,其商和余數(shù)均采用補(bǔ)碼形式表示,余數(shù)與被除數(shù)同符號(hào)。當(dāng)除數(shù)為零或商超過(guò)了規(guī)定數(shù)據(jù)類(lèi)型所能表示的范圍時(shí),將會(huì)出現(xiàn)溢出現(xiàn)象,產(chǎn)生一個(gè)中斷類(lèi)型碼為“0”的中斷。執(zhí)行除法指令后標(biāo)志位無(wú)定義。
      九、BCD算術(shù)運(yùn)算
      十進(jìn)制數(shù)在機(jī)器中采用BCD碼表示,以壓縮格式存放,即一個(gè)字節(jié)存儲(chǔ)2位BCD碼,BCD加減法是在二進(jìn)制加減運(yùn)算的基礎(chǔ)上,對(duì)其二進(jìn)制結(jié)果進(jìn)行調(diào)整,將結(jié)果調(diào)整成BCD碼表示形式。

      (1) 格式:DAA
      功能:將存放在AL中的二進(jìn)制和數(shù),調(diào)整為壓縮格式的BCD碼表示形式。
      調(diào)整方法:若AL中低4位大于9或標(biāo)志AF=1(表示低4位向高4位有進(jìn)位),則
             AL+6→AL,1→AF,
    若AL中高4位大于9,或標(biāo)志CF=1,(表示高4位有進(jìn)位),則
             AL+60H→AL,1→CF,
      DAA指令一般緊跟在ADD或ADC指令之后使用,影響標(biāo)志位為SF,ZF,AF,PF,CF。OF無(wú)定義。
      例 3.33
      ADD AL,BL
      DAA
      (2) 格式:DAS
      功能:將存放在AL中的二進(jìn)制差數(shù),調(diào)整為壓縮的BCD碼表示形式。
      調(diào)整方法:若AL中低4位大于9或標(biāo)志AF=1(表示低4位向高位借位),則
             AL-6→AL,1→AF
    若AL中高4位大于9或標(biāo)志CF=1(表示高4位向高位借位),則
             AL-60H→AL,1→CF
      DAS指令一般緊跟在SUB或SBB指令之后使用,影響標(biāo)志位為SF,ZF,AF,PF,CF。OF無(wú)定義。
      例 3.34
      SUB AL,BL
      DAS
      十、ASCII算術(shù)運(yùn)算
      數(shù)字0~9的ASCII碼為30H~39H,機(jī)器采用一個(gè)字節(jié)存放一位ASCII碼,對(duì)于ASCII碼的算術(shù)運(yùn)算是在二進(jìn)制運(yùn)算基礎(chǔ)上進(jìn)行調(diào)整。調(diào)整指令有加、減、乘、除四種調(diào)整指令。
      (1) 格式:AAA
      功能:將存放在AL中的二進(jìn)制和數(shù),調(diào)整為ASCII碼表示的結(jié)果。
      調(diào)整方法:若AL中低4位小于或等于9,僅AL中高4位清0,AF→CF。若AL中低4位大于9或標(biāo)志AF=1(進(jìn)位),則AL+6→AL,AH+1→AH,1→AF,AF→CF,AL中高4位清0。
      AAA指令一般緊跟在ADD或ADC指令之后使用,影響標(biāo)志位為AF,CF。其它標(biāo)志位無(wú)定義。
      例 3.35
      MOV AX,0036H
      ADD,AL,35H
      AAA;AX=0101H
      (2) 格式:AAS
      功能:將存放在AL中的二進(jìn)制差數(shù),調(diào)整為ASCII碼表示形式
      調(diào)整方法:若AL中低4位小于等于9,僅AL中高4位清0,AF→CF。若AL中低4位大于9或標(biāo)志AF=1,則AL-6→AL,AH-1→AH,1→AF,AF→CF,AL中高4位清0。
      AAS指令一般緊跟在SUB,SBB指令之后使用,影響標(biāo)志位為AF,CF。其它標(biāo)志位無(wú)定義。
      例 3.36
      MOV AX,0132H
      SUB AL,35H
      AAS;AX=0007H
      (3) 格式:AAM
      功能:將存放在AL中的二進(jìn)制積數(shù),調(diào)整為ASCII碼表示形式。
      調(diào)整方法:AL/10商→AH,余數(shù)→AL
      AAM指令一般緊跟在MUL指令之后使用,影響標(biāo)志位為SF,ZF,PF。其它標(biāo)志位無(wú)定義。
      例 3.37
      MOV AL,07H
      MOV BL,09H
      MUL BL;AX=003FH
      AAM;AX=0603H
      (4) 格式:AAD
      功能:將AX中兩位非壓縮BCD碼(一個(gè)字節(jié)存放一位BCD碼),轉(zhuǎn)換為二進(jìn)制數(shù)的表示形式。
      調(diào)整方法:AH10+AL→AL0→AH
      AAD指令用于二進(jìn)制除法DIV操作之前,影響的標(biāo)志位為SF,ZF,PF。其它標(biāo)志位無(wú)定義。
      例 3.38
      MOV AX,0605H
      MOV BL,09H
      AAD;AX=0041H
      DIV BL;AX=0207H
      使用該類(lèi)指令應(yīng)注意,加法、減法和乘法調(diào)整指令都是緊跟在算術(shù)運(yùn)算指令之后,將二進(jìn)制的運(yùn)算結(jié)果調(diào)整為非壓縮BCD碼表示形式,而除法調(diào)整指令必須放在除法指令之前進(jìn)行,以避免除法出現(xiàn)錯(cuò)誤的結(jié)果。
      使用算術(shù)運(yùn)算類(lèi)指令應(yīng)注意:
      ·如果沒(méi)有特別規(guī)定,參與運(yùn)算的兩個(gè)操作數(shù)數(shù)據(jù)類(lèi)型必須一致,且只允許一個(gè)為存儲(chǔ)器操作數(shù);
      ·如果參與運(yùn)算的操作數(shù)只有一個(gè),且為存儲(chǔ)器操作數(shù),必須使用PTR偽指令說(shuō)明數(shù)據(jù)類(lèi)型;
      ·操作數(shù)不允許為段寄存器。
      ·目的操作數(shù)不允許為立即數(shù);
      ·如果是存儲(chǔ)器尋址,則存儲(chǔ)器各種尋址方式均可使用。
      3.3.3邏輯運(yùn)算指令
      一、邏輯指令
      1邏輯與指令
      格式:AND DEST,SRC
      功能:目的操作數(shù)和源操作數(shù)按位進(jìn)行邏輯與運(yùn)算,結(jié)果存目的操作數(shù)中。源操作數(shù)可以是通用寄存器、存儲(chǔ)器或立即數(shù)。目的操作數(shù)可以是通用寄存器或存儲(chǔ)器操作數(shù)。
      例 3.39
      AND AL,BL
      AND EBX,ECX
      AND [DI],1101H
      AND指令常用于將操作數(shù)中某位清0(稱(chēng)屏蔽),只須將要清0的位與0,其它不變的位與1即可。
      例 3.40  AND AL,0FH;將AL中高4位清0,低4位保持不變。
      AND指令影響標(biāo)志位為SF,ZF,PF,并且使OF=CF=0。
      2邏輯或指令
      格式:OR DEST,SRC
      功能:目的操作數(shù)和源操作數(shù)按位進(jìn)行邏輯或運(yùn)算,結(jié)果存目的操作數(shù)中。源操作數(shù)可以是通用寄存器、存儲(chǔ)器或立即數(shù)。目的操作數(shù)可以是通用寄存器或存儲(chǔ)器操作數(shù)。
      例 3.41
      OR
    AX,BX
      OR ECX,[EAX]
      OR指令常用于將操作數(shù)中某位置1,只須將要置1的位或1,其它不改變的位或0即可。
      例 3.42  OR AL,80H;將AL中最高位置1。
      OR指令影響標(biāo)志位為SF,ZF,PF。并且使OF=CF=0。
      3邏輯異或指令
      格式:XOR DEST,SRC
      功能:目的操作數(shù)和源操作數(shù)按位進(jìn)行邏輯異或運(yùn)算,結(jié)果送目的操作數(shù)。源操作數(shù)可以是通用寄存器、存儲(chǔ)器或立即數(shù)。目的操作數(shù)可以是通用寄存器或存儲(chǔ)器操作數(shù)。
      例 3.43
      XOR AX,BX
      XOR [BX],1010H
      XOR指令常用于將操作數(shù)中某些位取反,只須將要取反的位異或1,其它不改變的位異或0即可。
      例 3.44  XOR AL,OFH;將AL中低4位取反,高4位保持不變。
      XOR指令影響標(biāo)志位為SF,ZF,PF,并且使OF=CF=0。

      4邏輯非指令
      格式:NOT DEST
      功能:對(duì)目的操作數(shù)按位取反,結(jié)果回送目的操作數(shù)。目的操作數(shù)可以為通用寄存器或存儲(chǔ)器。
      例 3.45
      NOT EAX
      NOT BYTE PTR [BX]
      NOT指令對(duì)標(biāo)志位無(wú)影響。
      5測(cè)試指令
      格式:TEST DEST,SRC
      功能:目的操作數(shù)和源操作數(shù)按位進(jìn)行邏輯與操作,結(jié)果不回送目的操作數(shù)。源操作數(shù)可以為通用寄存器、存儲(chǔ)器或立即數(shù)。目的操作數(shù)可以為通用寄存器或存儲(chǔ)器操作數(shù)。
      例 3.46
      TEST DWORD PTR [BX],80000000H
      TEST AL,CL
      TEST指令常用于測(cè)試操作數(shù)中某位是否為1,而且不會(huì)影響目的操作數(shù)。如果測(cè)試某位的狀態(tài),對(duì)某位進(jìn)行邏輯與1的運(yùn)算,其它位邏輯與0,然后判斷標(biāo)志位。運(yùn)算結(jié)果為0,ZF=1,表示被測(cè)試位為0;否則ZF=0,表示被測(cè)試位為1。
      例 3.47  TEST AL,80H;測(cè)試AL中最高位
            JNZ NEXT;如果最高位為1,轉(zhuǎn)到標(biāo)志NEXT處。
      TEST指令影響標(biāo)志位為SF,ZF,PF,并且使OF=CF=0。
      二、移位指令
      移位指令對(duì)操作數(shù)按某種方式左移或右移,移位位數(shù)可以由立即數(shù)直接給出,或由CL間接給出。移位指令分一般移位指令和循環(huán)移位指令。
      1一般移位指令
      (1) 算術(shù)/邏輯左移指令。
      格式:SAL DEST,OPRD
         SHL DEST,OPRD
      功能:按照操作數(shù)OPRD規(guī)定的移位位數(shù),對(duì)目的操作數(shù)進(jìn)行左移操作,最高位移入CF中。每移動(dòng)一位,右邊補(bǔ)一位0。如圖312(a)所示。目的操作數(shù)可以為通用寄存器或存儲(chǔ)器操作數(shù)。
      SAL,SHL指令影響標(biāo)志位OF,SF,ZF,PF,CF。

    圖 3.12  移位指令示意圖 


      例 3.48
      SHL BYTE PTR [DI],2
      SAL BX,CL
      (2) 算術(shù)右移指令。
      格式:SAR DEST,OPRD
      功能:按照操作數(shù)OPRD規(guī)定的移位次數(shù),對(duì)目的操作數(shù)進(jìn)行右移操作,最低位移至CF中,最高位(即符號(hào)位)保持不變。如圖312(b)所示。目的操作數(shù)可以為通用寄存器或存儲(chǔ)器操作數(shù)。
      SAR指令影響標(biāo)志位OF,SF,ZF,PF,CF。
      例 3.49
      SAR AL,5
      SAR WORD PTR /[ECX/],CL
      (3) 邏輯右移指令。
      格式:SHR DEST,SRC
      功能:按照操作數(shù)OPRD規(guī)定的移位位數(shù),對(duì)目的操作數(shù)進(jìn)行右移操作,最低位移至CF中。每移動(dòng)一位,左邊補(bǔ)一位0。如圖312(c)所示,目的操作數(shù)可以為通用寄存器或存儲(chǔ)器操作數(shù)。
      SHR指令影響標(biāo)志位OF,SF,ZF,PF,CF。
      例 3.50
      SHR BYTE PTR [SI],3
      SHR EDX,CL
      算術(shù)/邏輯左移,只要結(jié)果未超出目的操作數(shù)所能表達(dá)的范圍,每左移一次相當(dāng)于原數(shù)乘2。算術(shù)右移只要無(wú)溢出,每右移一次相當(dāng)于原數(shù)除以2。
      2循環(huán)移位指令
      格式:ROL DEST,OPRD
         ROR DEST,OPRD
         RCL DEST,OPRD
         RCR DEST,OPRD
      功能:循環(huán)左移指令ROL,見(jiàn)圖313(a)所示,目的操作數(shù)左移,每移位一次,其最高位移入最低位,同時(shí)最高位也移入進(jìn)位標(biāo)志CF。循環(huán)右移指令 ROR見(jiàn)圖313(b)所示,目的操作數(shù)右移,每移位一次,其最低位移入最高位,同時(shí)最低位也移入進(jìn)位標(biāo)志CF。
      帶進(jìn)位循環(huán)左移指令RCL,見(jiàn)圖313(c)所示,目的操作數(shù)左移,每移動(dòng)一次,其最高位移入進(jìn)位標(biāo)志CF,CF移入最低位。帶進(jìn)位循環(huán)右移指令RCR,見(jiàn)圖313(d)所示,目的操作數(shù)右移,每移動(dòng)一次,其最低位移入進(jìn)位標(biāo)志CF,CF移入最高位。

    圖 3.13  循環(huán)移位指令


      目的操作數(shù)可以為通用寄存器或存儲(chǔ)器操作數(shù)。循環(huán)移位指令影響標(biāo)志位CF,OF。其它標(biāo)志位無(wú)定義。
      例 3.51
      ROL AL,CL
      ROR BX,5
      RCL ECX,3
      RCR BYTE PTR [SI],CL
      例 3.52  將一個(gè)2位數(shù)壓縮的BCD碼轉(zhuǎn)換成二進(jìn)制數(shù)。
       ·MODEL SMALL
       ·DATA
      BCD DB 01011001B
      BIN DB?
        CODE
       ·START UP
        MOV AL,BCD
        MOV BL,AL
        AND BL,0FH
        AND AL,0F0H
        MOV CL,4
        ROR AL,CL
        MOV BH,0AH
        MUL BH
        ADD AL,BL
        MOV BIN,AL
       ·EXIT
        END
      3雙精度移位指令
      格式:SHLD DEST,SRC,OPRD
         SHRD DEST,SRC,OPRD
      功能:對(duì)于由目的操作數(shù)DEST和源操作數(shù)SRC構(gòu)成的雙精度數(shù),按照操作數(shù)OPRD給出的移位位數(shù),進(jìn)行移位。SHLD是對(duì)目的操作數(shù)進(jìn)行左移,如 圖314(a)所示,SHRD是對(duì)目的操作數(shù)進(jìn)行右移,如圖314(b)所示。先移出位送標(biāo)志位CF,另一端空出位由SRC移入DEST中,而SRC 內(nèi)容保持不變。目的操作數(shù)可以是16位或32位通用寄存器或存儲(chǔ)器操作數(shù)。源操作數(shù)SRC允許為16位或32位通用寄存器。操作數(shù)OPRD可以為立即數(shù)或 CL。目的操作數(shù)和源操作數(shù)SRC數(shù)據(jù)類(lèi)型必須一致。

    圖 3.14  雙精度移位指令

      SHLD,SHRD指令常用于位串的快速移位、嵌入和刪除等操作,影響標(biāo)志位為SF,ZF,PF,CF,其它標(biāo)志位無(wú)定義。
      三、位操作指令
    位操作指令包括位測(cè)試和位掃描指令,可以直接對(duì)一個(gè)二進(jìn)制位進(jìn)行測(cè)試,設(shè)置和掃描。
      1位測(cè)試和設(shè)置指令
      格式:BT DEST,SRC
         BTC DEST,SRC
         BTR DEST,SRC
         BTS DEST,SRC
      功能:按照源操作指定的位號(hào),測(cè)試目的操作數(shù),當(dāng)指令執(zhí)行時(shí),被測(cè)試位的狀態(tài)被復(fù)制到進(jìn)位標(biāo)志CF。
      BT將SRC指定的DEST中一位的數(shù)值復(fù)制到CF。BTC將SRC指定的DEST中一位的數(shù)值復(fù)制到CF,且將DEST中該位取反。BTR將SRC 指定的DEST中一位的數(shù)值復(fù)制到CF,且將DEST中該位復(fù)位。BTS將SRC指定的DEST中一位的數(shù)值復(fù)制到CF,且將DEST中該位置位。
      目的操作數(shù)為16位或32位通用寄存器或存儲(chǔ)器,源操作數(shù)為16位或32位通用寄存器,以及8位立即數(shù),當(dāng)源操作數(shù)為通用寄存器時(shí),必須同目的操作數(shù)類(lèi)型一致。源操作數(shù)SRC以?xún)煞N方式給出目的操作數(shù)的位號(hào),即
      · SRC為8位立即數(shù),以二進(jìn)制形式直接給出要操作的位號(hào);
      · SRC為通用寄存器,如果DEST為通用寄存器,則SRC中二進(jìn)制值直接給出要操作的位號(hào)。如果DEST為存儲(chǔ)器操作數(shù),通用寄存器SRC為帶符號(hào)整數(shù), SRC的值除以DEST的長(zhǎng)度所得到的商作為DEST的相對(duì)偏移量,余數(shù)直接作為要操作的位號(hào)。DEST的有效地址為DEST給出的偏移地址和DEST相 對(duì)偏移量之和。
      BT,BTC,BTR,BTS指令影響CF標(biāo)志位,其它標(biāo)志位無(wú)定義。
      例 3.53
      MOV AX,1234H
      MOV ECX,5
      BT AX,CX      ?。籆F=1AX=1234H
      BTC AX,5      ??;CF=1;AX=1214H
      BTS AX,CX;      ;CF=0AX=1234H
      BTR EAX,ECX      ;CF=1EAX=00001214H

      例 3.54

          ·MODEL SMALL
          ·586
          ·DATA
       DATA1 DW 1234H,5678H
          ·CODE
          ·START UP
           BTC DATA1,3;CF=0(DATA1)=123CH
           MOV CX,20
           BTR DATA1,CX;CF=1[DATA+2]=5668H
          ·EXIT
           END
      2位掃描指令
      格式:BSFDEST,SRC
         BSRDEST,SRC
      功能:BSF從低位開(kāi)始掃描源操作數(shù),若所有位都是0,則ZF=0,否則ZF=1。并且將第一個(gè)出現(xiàn)1的位號(hào)存入目的操作數(shù)。BSR從高位開(kāi)始掃描源操作數(shù),若所有位都是0,則ZF=0,否則ZF=1。并且將第一個(gè)出現(xiàn)1的位號(hào)存入目的操作數(shù)。
      源操作數(shù)可以為16位32位通用寄存器或存儲(chǔ)器。目的操作數(shù)為16位或32位通用寄存器。源操作數(shù)和目的操作數(shù)類(lèi)型必須一致。
      BSF,BSR指令影響ZF標(biāo)志位,其它標(biāo)志位無(wú)定義。
      例 3.55
      MOV EBX,0F333EE00H
      BSR EAX,EBX;ZF=1EAX=0000001FH=31
      BSF EDX,EBX;ZF=1EDX=00000009H
      3進(jìn)位標(biāo)志指令
      (1) 格式:CLC。功能:清除進(jìn)位標(biāo)志。
      (2) 格式:STC。功能:設(shè)置進(jìn)位標(biāo)志。
      (3) 格式:CMC。功能:進(jìn)位標(biāo)志取反。
      4條件設(shè)置字節(jié)指令
      條件設(shè)置指令用于根據(jù)條件設(shè)置某一狀態(tài)字節(jié)或標(biāo)志字節(jié),見(jiàn)表33。
      格式:SETcondDEST
      功能:測(cè)試條件(cond)若為真,則將目的操作數(shù)置01H,否則置00H。目的操作數(shù)允許為8位通用寄存器或8位存儲(chǔ)器操作數(shù)。
      條件cond與條件轉(zhuǎn)移指令中的條件相同,共分三類(lèi)。
      (1) 以標(biāo)志位狀態(tài)為條件可以測(cè)試的標(biāo)志位為ZF,SF,OF,CF,PF。
      (2) 以?xún)蓚€(gè)無(wú)符號(hào)數(shù)比較為條件條件為高于、高于等于、低于、低于等于。
      (3) 以?xún)蓚€(gè)帶符號(hào)數(shù)比較為條件條件為大于、大于等于、小于、小于等于。
      SET指令不影響標(biāo)志位。
      使用邏輯運(yùn)算類(lèi)指令應(yīng)注意:
      · 如果沒(méi)有特別規(guī)定,參與運(yùn)算的兩個(gè)操作數(shù)類(lèi)型必須一致,且只允許一個(gè)為存儲(chǔ)器操作數(shù);
      · 如果參與運(yùn)算的操作數(shù)只有一個(gè),且為存儲(chǔ)器操作數(shù),必須使用PTR偽指令說(shuō)明其數(shù)據(jù)類(lèi)型; 
      · 操作數(shù)不允許為段寄存器;
      · 目的操作數(shù)不允許為立即數(shù);
      · 如果是存儲(chǔ)器尋址,則前面介紹的各種存儲(chǔ)器尋址方式均可使用。

    表 3.3  條件設(shè)置字節(jié)指令


      3.3.4控制轉(zhuǎn)移類(lèi)指令
      計(jì)算機(jī)執(zhí)行程序一般是順序地逐條執(zhí)行指令。但經(jīng)常須要根據(jù)不同條件做不同的處理,有時(shí)需要跳過(guò)幾條指令,有時(shí)需要重復(fù)執(zhí)行某段程序,或者轉(zhuǎn)移到另一個(gè)程序段去執(zhí)行。用于控制程序流程的指令包括轉(zhuǎn)移、循環(huán)、過(guò)程調(diào)用和中斷調(diào)用。
      一、轉(zhuǎn)移指令
      1無(wú)條件轉(zhuǎn)移指令
      格式:JMP TARGET
      功能:使程序無(wú)條件地轉(zhuǎn)移到指令規(guī)定的目的地址TARGET去執(zhí)行指令。轉(zhuǎn)移分為短轉(zhuǎn)移、段內(nèi)轉(zhuǎn)移(近程轉(zhuǎn)移)和段間轉(zhuǎn)移(遠(yuǎn)程轉(zhuǎn)移)。
      (1) 段內(nèi)直接轉(zhuǎn)移:
      格式:JMP SHORT TARGET;短轉(zhuǎn)移
      JMP NEAR PTR TARGET;近程轉(zhuǎn)移
      功能:采用相對(duì)尋址將當(dāng)前IP值(即JMP指令下一條指令的地址)與JMP指令中給出的偏移量之和送IP中。段內(nèi)短轉(zhuǎn)移(SHORT)指令偏移量為8 位,允許轉(zhuǎn)移偏移值的范圍為-128~+127。段內(nèi)近程轉(zhuǎn)移(NEAR)指令在16位指令模式下,偏移量為16位,允許轉(zhuǎn)移偏移值范圍為-215~+ 215-1。在32位指令模式下,偏移值范圍為-231~+231-1。

      例 3.56
         JMP NEXT
          
      NEXT:MOV AL,BL
      本例為無(wú)條件轉(zhuǎn)移到本段內(nèi),標(biāo)號(hào)為NEXT的地址去執(zhí)行指令,匯編程序可以確定目的地址與JMP指令的距離。
      (2) 段內(nèi)間接轉(zhuǎn)移:
      格式:JMP REG
      JMP NEAR PTR [REG]
      功能:段內(nèi)間接轉(zhuǎn)移,其中JMP REG指令地址在通用寄存器中,將其內(nèi)容直接送IP實(shí)現(xiàn)程序轉(zhuǎn)移。JMP NEAR PTR [REG]指令地址在存儲(chǔ)器中,默認(rèn)段寄存器根據(jù)參與尋址的通用寄存器來(lái)確定,將指定存儲(chǔ)單元的字取出直接送IP實(shí)現(xiàn)程序轉(zhuǎn)移。在16位指令模式,轉(zhuǎn)移偏 移值范圍為。在32位指令模式,轉(zhuǎn)移偏移值范圍為。
      例 3.57 設(shè)DS=1000HEBX=00002000H。
      JMP BX         ?。粚?000H送IP
      JMP NEAR PTR [BX]     ;將地址1000∶2000單元存放的一個(gè)字送IP
      JMP NEAR PTR [EBX]   ?。粚⒍芜x擇符為1000H,偏移地址為00002000H單元存放的雙字送EIP。
      (3) 段間直接轉(zhuǎn)移:
      格式:JMP FAR PTR TARGET
      功能:段間直接轉(zhuǎn)移,F(xiàn)AR PTR說(shuō)明標(biāo)號(hào)TARGET具有遠(yuǎn)程屬性。將指令中由TARGET指定的段值送CS,偏移地址送IP。
      例 3.58 JMP FAR PTR NEXT。
      在16位指令模式下,段基地送CS,偏移地址為16位,轉(zhuǎn)移偏移值范圍;在32位指令模式下,代碼段選擇符送CS,偏移地址為32位,轉(zhuǎn)移偏移值范圍為。
      (4) 段間間接轉(zhuǎn)移:
      格式:JMP FAR PTR [Reg]
      功能:段間間接轉(zhuǎn)移,由FAR PTR [Reg]指定的存儲(chǔ)器操作數(shù)作為轉(zhuǎn)移地址。
    在16位指令模式下,存儲(chǔ)器操作數(shù)為32位,包括16位段基址和16位偏移地址。
      例 3.59
      JMP FAR PTR [BX]      ;數(shù)據(jù)段雙字存儲(chǔ)單元低字內(nèi)容送IP
                   ??;數(shù)據(jù)段雙字存儲(chǔ)單元高字內(nèi)容送CS
      在32位指令模式下,存儲(chǔ)器操作數(shù)包括16位選擇符。
      例 3.60  JMP FAR PTR [EAX]
      指令中包含指向目標(biāo)地址指針的門(mén)描述符或TSS描述符的指針,其所指的存儲(chǔ)器操作數(shù)中僅選擇符部分有效,指示調(diào)用門(mén)、任務(wù)門(mén)或TSS描述符起作用,而偏移部分不起作用。
      2條件轉(zhuǎn)移指令
      該類(lèi)指令是根據(jù)上一條指令對(duì)標(biāo)志寄存器中標(biāo)志位的影響來(lái)決定程序執(zhí)行的流程,若滿(mǎn)足指令規(guī)定的條件,則程序轉(zhuǎn)移;否則程序順序執(zhí)行。
    條件轉(zhuǎn)移指令的轉(zhuǎn)移范圍為段內(nèi)短轉(zhuǎn)移或段內(nèi)近程轉(zhuǎn)移,不允許段間轉(zhuǎn)移。段內(nèi)短轉(zhuǎn)移(short)的轉(zhuǎn)移偏移值范圍為-128~+127。段內(nèi)近程轉(zhuǎn)移,在16位指令模式下轉(zhuǎn)移偏移值范圍為,在32位指令模式下轉(zhuǎn)移偏移值范圍為。
      條件轉(zhuǎn)移指令包括四類(lèi):?jiǎn)螛?biāo)志位條件轉(zhuǎn)移;無(wú)符號(hào)數(shù)比較條件轉(zhuǎn)移;帶符號(hào)數(shù)比較條件轉(zhuǎn)移;測(cè)試CX條件轉(zhuǎn)移。
      格式:Jcc TARGET
      功能:若測(cè)試條件‘CC’為真,則轉(zhuǎn)移到目標(biāo)地址TARGET處執(zhí)行程序。否則順序執(zhí)行。
      (1) 單標(biāo)志位條件轉(zhuǎn)移指令,見(jiàn)表34。
      例 3.61 JZ NEXT;若標(biāo)志ZF=1則轉(zhuǎn)移到標(biāo)號(hào)NEXT處執(zhí)行。
      (2) 無(wú)符號(hào)數(shù)比較條件轉(zhuǎn)移,見(jiàn)表35。
      例 3.62 JA NEXT;無(wú)符號(hào)數(shù)A與B比較,若A>B則轉(zhuǎn)移到標(biāo)號(hào)NEXT處執(zhí)行程序


              
    表 3.4 單標(biāo)志位條件轉(zhuǎn)移指令

    表 3.5 無(wú)符號(hào)數(shù)比較條件轉(zhuǎn)移指令

    表 3.6 帶符號(hào)數(shù)比較條件轉(zhuǎn)移指令

               

      例 3.63  JG NEXT;帶符號(hào)數(shù)A與B比較,若A>B則轉(zhuǎn)移到標(biāo)號(hào)NEXT。
      (4) 測(cè)試CX條件轉(zhuǎn)移,見(jiàn)表37。


    表 3.7 測(cè)試CX條件轉(zhuǎn)移指令


      例 3.64 JCXZ TARGET;CX=0轉(zhuǎn)移到標(biāo)號(hào)TARGET處。
           JECXZ TARGET;ECX=0轉(zhuǎn)移到標(biāo)號(hào)TARGET處。
      條件轉(zhuǎn)移指令一般緊跟在CMP或TEST指令之后,判斷執(zhí)行CMP或TEST指令對(duì)標(biāo)志位的影響來(lái)決定是否轉(zhuǎn)移。
      例 3.65 符號(hào)函數(shù)
          
      假設(shè)x為某值且存放在寄存器AL中,試編程將求出的函數(shù)值f(x)存放在AH中。
        ·MODEL TINY
        ·CODE
        ·STARTUP
         CMPAL,0
         JGE BIG
         MOV AL,0FFH
         JMP DONE
      BIG: JE DONE
         MOV AL,1
      DONE:MOV AH,AL
       ·EXIT
        END
      例 3.66 編程實(shí)現(xiàn)把BX寄存器內(nèi)的二進(jìn)制數(shù)用十六進(jìn)制數(shù)的形式在屏幕上顯示出來(lái)。
         ·MODEL TINY
         ·CODE
         ·STARTUP
          MOV CH,4
      AGAIN: MOV CL,4
          ROL BX,CL
          MOV AL,BL
          ANDAL,0FH
          OR AL,30H
          CMP AL,3AH
          JB NEXT
          ADD AL,07H
       NEXT: MOV DL,AL;DL←要顯示的ASCII碼
          MOV AH,2;顯示
          INT 21H
          DECCH
          JNZ AGAIN
         ·EXIT
          END
      二、循環(huán)控制指令
      這類(lèi)指令用(E)CX計(jì)數(shù)器中的內(nèi)容控制循環(huán)次數(shù),先將循環(huán)計(jì)數(shù)值存放在(E)CX中,每循環(huán)一次(E)CX內(nèi)容減1,直到(E)CX為0時(shí)循環(huán)結(jié)束。
      格式:LOOPcc TARGET
      功能:將(E)CX內(nèi)容減1,不影響標(biāo)志位,若(E)CX不等于0,且測(cè)試條件‘CC’成立,則轉(zhuǎn)移到目標(biāo)地址TARGET處執(zhí)行程序。轉(zhuǎn)移范圍為-128~+127。如表38所示。

    表3.8 循環(huán)控制指令



      例 3.67 計(jì)算
          ·MODEL TINY
          ·CODE
          ·STARTUP
           XOR EAX,EAX
           MOV EDX,1
           MOV ECX,1000
       SUM:  ADD EAX,EDX
           INC EDX
           LOOPD SUM
          ·EXIT
           END
      例 3.68 找出以ARRAY為首地址的100個(gè)字?jǐn)?shù)組中的第一個(gè)非0項(xiàng),送AX寄存器中。
         ·MODELSMALL
         ·DATA
          ARRAYDW 0,0,0,0,1010H,…;(100個(gè)字)
         ·CODE
         ·STARTUP
          MOV CX,64H
          LEA BX,ARRAY
          MOV SI,0FFFEH
      ZERO: INC SI
          INC SI
          CMP WORD PTR [BX+SI],0
          LOOPZ ZERO
          MOV AX,[BX+SI]
         ·EXIT
          END
      關(guān)于過(guò)程調(diào)用和返回指令將在子程序一節(jié)中介紹。
      3.3.5串操作指令
      80x86提供處理字符串的操作。串指連續(xù)存放在存儲(chǔ)器中的一些數(shù)據(jù)字節(jié)、字或雙字。串操作允許程序?qū)B續(xù)存放大的數(shù)據(jù)塊進(jìn)行操作。
      串操作通常以DS:(E)SI來(lái)尋址源串,以ES:(E)DI來(lái)尋址目的串,對(duì)于源串允許段超越。(E)SI或(E)DI這兩個(gè)地址指針在每次串操作 后,都自動(dòng)進(jìn)行修改,以指向串中下一個(gè)串元素。地址指針修改是增量還是減量由方向標(biāo)志來(lái)規(guī)定。當(dāng)DF=0,(E)SI及(E)DI的修改為增量;當(dāng)DF= 1,(E)SI及(E)DI的修改為減量。根據(jù)串元素類(lèi)型不同,地址指針增減量也不同,在串操作時(shí),字節(jié)類(lèi)型SI,DI加、減1;字類(lèi)型SI,DI加、減 2;雙字類(lèi)型ESI,EDI加、減4。如果需要連續(xù)進(jìn)行串操作,通常加重復(fù)前綴。重復(fù)前綴可以和任何串操作指令組合,形成復(fù)合指令,見(jiàn)表39。
      一、重復(fù)前綴指令


    表 3.9 重復(fù)前綴指令


      二、方向標(biāo)志指令
      格式:CLD/STD
      功能:CLD為清除方向標(biāo)志,即將DF置‘0’。STD為設(shè)置方向標(biāo)志,即將DF置‘1’。
      三、串傳送指令
      基本格式:[REP]MOVS DESTS, SRCS
      [REP] MOVSB/MOVSW/MOVSD
      功能:將DS:(E)SI規(guī)定的源串元素復(fù)制到ES:(E)DI規(guī)定的目的串單元中,見(jiàn)表310。

    表 3.10 MOVS指令



      該指令對(duì)標(biāo)志位無(wú)影響。
      如果加重復(fù)前綴REP,則可以實(shí)現(xiàn)連續(xù)存放的數(shù)據(jù)塊的傳送,直到(E)CX=0為止。
      在16位指令模式下,使用SI,DI,CX寄存器;在32位指令模式下,使用ESI,EDI,ECX寄存器。
      例 3.69
       ·MODEL SMALL
       ·DATA
     SRC  DB 1,2,3,…(100個(gè)字節(jié))
     DEST DB 100DUP(?)
       ·CODE
       ·STARTUP
        MOV AX,@DATA
        MOV ES,AX
        MOV CX,100
        LEA SI,SRC
        LEA DI,DEST
        CLD
        REP MOVSB
       ·EXIT
        END
      該程序?qū)⑵鹗嫉刂窞镾RC的100個(gè)字節(jié)內(nèi)容傳送到起始地址為DEST的存儲(chǔ)單元。
      四、串比較指令
      基本格式:[REPE/Z] [REPNZ/NE] CMPS DESTS, SRCS
           [REPE/Z] [REPNZ/NE] CMPSB/CMPSW/CMPSD
      功能:由DS:(E)SI規(guī)定的源串元素減去ES:(E)DI指出的目的串元素,結(jié)果不回送,僅影響標(biāo)志位CF,AF,PF,OF,ZF,SF。當(dāng)源 串元素與目的串元素值相同時(shí),ZF=1;否則ZF=0。每執(zhí)行一次串比較指令,根據(jù)DF的值和串元素?cái)?shù)據(jù)類(lèi)型自動(dòng)修改(E)SI和(E)DI。
      在串比較指令前加重復(fù)前綴REPE/Z,則表示重復(fù)比較兩個(gè)字符串,若兩個(gè)字符串的元素相同則比較到(E)CX=0為止,否則結(jié)束比較。在串比較指令 前加重復(fù)前綴REPNE/NZ,則表示若兩個(gè)字符串元素不相同時(shí),重復(fù)比較直到(E)CX=0為止,否則結(jié)束比較。
      例 3.70 編程實(shí)現(xiàn)兩個(gè)串元素比較,如相同則將全“1”送SUT單元,否則全“0”送SUT單元。
          ·MODEL SMALL
          ·DATA
        DEST DB ‘A B C D E F G H’
        SRC  DB ‘A B C E F F F E’
        SUT  DB?
          ·CODE
          ·STARTUP
           MOV AX,@DATA
           MOV ES,AX
           MOV CX,8
           LEA SI,DEST
           LEA DI,SRC
           CLD
           REPE CMPSB
           JZ EQUL;ZF=1;CX=0
           MOV BH,0;CX≠0,ZF=0
           JMP DONE
       EQUL: MOV BH,0FFH
       DONE: MOV SUT,BH
          ·EXIT
           END
      五、串掃描指令
      格式①: [REPE/Z] [REPNE/NZ] SCAS DESTS
      格式②: [REPE/Z] [REPNE/NZ] SCASB/SCASW/SCASD
      功能:由AL,AX或EAX的內(nèi)容減去ES:(E)DI規(guī)定的目的串元素,結(jié)果不回送,僅影響標(biāo)志位CF,AF,PF,SF,OF,ZF。當(dāng)AL, AX或EAX的值與目的串元素值相同時(shí),ZF=1;否則ZF=0。每執(zhí)行一次串掃描指令,根據(jù)DF的值和串元素?cái)?shù)據(jù)類(lèi)型自動(dòng)修改(E)DI。
      在串掃描指令前加重復(fù)前綴REPE/Z,則表示目的串元素值和累加器值相同時(shí)重復(fù)掃描,直到CX/ECX=0為止,否則結(jié)束掃描。若加重復(fù)前綴 REPNE/NZ,則表示當(dāng)目的串元素值與累加器值不相等時(shí),重復(fù)掃描直到CX/ECX=0時(shí)為止,否則結(jié)束掃描。
    該指令影響標(biāo)志位為CF,AF,PF,SF,OF,ZF。
      例 3.71 在內(nèi)存DEST開(kāi)始的6個(gè)單元尋找字符‘C’,如找到將字符‘C’的地址送ADDR單元,否則0送ADDR單元。
        ·MODEL SMALL
        ·DATA
      DEST DB ‘A B C D E F’
      ADDR DW?;存“C”的地址,所以設(shè)置為字類(lèi)型
        ·CODE
        ·STARTUP
         MOV AX,@DATA
         MOV ES,AX
         MOV CX,6
         LEA DI,DEST
         MOV AL,‘C’
         CLD
         REPNE SCASB
         JZ EQUL
         MOV DI,0
         JMP DONE
     EQUL: DEC DI
     DONE: MOV ADDR,DI
        ·EXIT
         END
      六、 串裝入指令
      格式:LODS SRCS
         LODSB/LODSW/LODSD
      功能:將DS:SI/ESI所指的源串元素裝入累加器(AL,AX,EAX)中,每裝入一次都按照DF值以及串元素類(lèi)型自動(dòng)修改地址指針SI/ESI,該指令一般不須加重復(fù)前綴,并且不影響標(biāo)志位。
      七、 串存儲(chǔ)指令
      格式:[REP] STOS DESTS
         [REP] STOSB/STOSW/STOSD
      功能:將累加器/[AL,AX,EAX/]中值存入ES:DI/EDI所指的目的串存儲(chǔ)單元中,每傳遞一次,都按DF值以及串元素類(lèi)型自動(dòng)修改地址指 針DI/EDI。若加重復(fù)前綴REP,則表示將累加器的值連續(xù)送目的串存儲(chǔ)單元,直到CX/ECX=0時(shí)為止。
    該指令不影響標(biāo)志位。
      3.3.6輸入/輸出指令
      一、 輸入指令
      格式:IN DEST, SRC
      功能:根據(jù)源操作數(shù)SRC給出的端口地址,將操作數(shù)從指定端口傳送到目的操作數(shù)DEST處,其中DEST為AL,AX或EAX,端口地址SRC可以直接形式給出8位端口地址,或由DX寄存器以間接形式給出。
      例 3.72
      IN AL,10H
      IN AX,20H
      IN EAX,30H
      IN AL,DX
      IN AX,DX
      IN EAX,DX
      二、 輸出指令
      格式OUT DEST, SRC
      功能:將源操作數(shù)SRC送到目的操作數(shù)DEST所指定的端口。其中源操作數(shù)SRC為AL,AX或EAX,目的操作數(shù)可以8位端口地址方式直接給出或以DX寄存器間接方式給出。
    使用輸入、輸出指令應(yīng)注意:
      · 直接尋址方式端口地址為8位,共有0~255個(gè)端口地址;
      · 間接尋址方式,只能用DX作為地址寄存器,尋址范圍為64K字節(jié);
      · 每個(gè)I/O地址對(duì)應(yīng)的端口的數(shù)據(jù)長(zhǎng)度為8位,傳送8位數(shù)據(jù)占用一個(gè)端口地址,傳送16位數(shù)據(jù)占用2個(gè)端口地址,傳送32位數(shù)據(jù)占用4個(gè)端口地址。
      三、 串輸入指令
      格式:[REP] INS DESTS, DX
      [REP] INSB/INSW/INSD
      功能:根據(jù)DX給出的端口地址,從外設(shè)讀入數(shù)據(jù)送入以ES:DI/EDI為地址的目的串存儲(chǔ)單元中,每輸入一次,均根據(jù)DF的值和串元素類(lèi)型自動(dòng)修改 DI/EDI的值。若加重復(fù)前綴REP,則表示連續(xù)從外設(shè)輸入串元素存入目的串存儲(chǔ)單元中,直到CX/ECX=0為止。
      例 3.73 從端口地址為1000H處取數(shù)存入內(nèi)存BLOCK單元。
         ·MODEL SMALL
         ·DATA
          BLOCKDB?
         ·CODE
         ·STARTUP
          MOV AX,@DATA
          MOV ES,AX
          CLD
          LEA DI,BLOCK
          MOV DX,1000H
          INS BLOCK,DX
         ·EXIT
          END
      四、串輸出指令
      格式:[REP] OUTS DX,SRCS
         [REP] OUTSB/OUTSW/OUTSD
      功能:將DS:SI/ESI所指的源串元素,按照DX寄存器指定的端口地址送往外設(shè),每輸出一次,均根據(jù)DF的值和串元素類(lèi)型自動(dòng)修改SI/ESI的值,若加重復(fù)前綴REP,則表示連續(xù)向外設(shè)輸出串元素,直到CX/ECX=0時(shí)為止。
      例 3.74 將內(nèi)存BLOCK為首地址的100個(gè)字符送往端口地址為2000H的外設(shè)。
         ·MODEL SMALL
         ·DATA
          BLOCKDB ‘A,B,…’(100個(gè)字符)
         ·CODE
         ·STARTUP
          CLD
          LEA SI,BLOCK
          MOV CX,100
          MOV DX,2000H
          REP OUTSB
         ·EXIT
          END
      在使用帶重復(fù)前綴的串輸入輸出指令時(shí),必須考慮端口的數(shù)據(jù)準(zhǔn)備或接收狀態(tài)。
      所有輸入輸出指令均不影響標(biāo)志位。
      3.3.7處理器控制
      一、 總線封鎖前綴
      格式:LOCK指令
      功能:LOCK為指令前綴,可以使LOCK引腳變成邏輯0,在LOCK引腳有效期間,禁止外部總線上的其它處理器存取帶有LOCK前綴指令的存儲(chǔ)器操作數(shù)。
      可加LOCK前綴的指令:
      (1) ADD/SUB/ADC/SBB/OR/XOR/AND Mem, Reg/imm;
      (2) NOT/NEG/INC/NEC Mem;
      (3) XCHG Reg, Mem或XCHG Mem, Reg;
      (4) BT/BTS/BRT/BTC Mem, Reg/imm。
      Mem為存儲(chǔ)器操作數(shù),Reg為通用寄存器,imm為立即數(shù)。
      二、空操作
      格式:NOP
      功能:空操作,除使IP/EIP增1外,不做任何工作。該指令不影響標(biāo)志位。
      三、處理器等待指令
      格式:WAIT
      功能:檢查BUSY引腳狀態(tài),等待協(xié)處理器完成當(dāng)前工作。
      四、處理器暫停指令
      格式:HLT
      功能:暫停程序的執(zhí)行。當(dāng)產(chǎn)生一個(gè)外部中斷或非屏蔽中斷時(shí),才繼續(xù)執(zhí)行下一條指令。
      3.3.8中斷指令與DOS功能調(diào)用
      一、中斷指令
      在實(shí)模式下,中斷矢量以4個(gè)字節(jié)存放在中斷矢量表中,中斷矢量表為1k字節(jié)(00000H~003FFH),中斷矢量表允許存放256個(gè)中斷矢量,每 個(gè)中斷矢量包含一個(gè)中斷服務(wù)程序地址(段值和16位偏移地址),中斷矢量地址指針由中斷類(lèi)型碼乘以4得到。
      在保護(hù)模式下,用中斷描述符表代替中斷矢量表,每個(gè)中斷由8個(gè)字節(jié)的中斷描述符來(lái)說(shuō)明,中斷描述符表允許256個(gè)中斷描述符,每個(gè)中斷描述符包含一個(gè)中斷服務(wù)地址(段選擇符、32位偏移地址、訪問(wèn)權(quán)限等)。中斷描述符地址指針由中斷類(lèi)型碼乘以8得到。

      中斷指令格式:INT n
      功能:產(chǎn)生中斷類(lèi)型碼為n的軟中斷,該指令包含中斷操作碼和中斷類(lèi)型碼兩部分,中斷類(lèi)型碼n為8位,取值范圍為0~255(00H~FFH)。
      軟中斷執(zhí)行過(guò)程:
      · 將標(biāo)志寄存器FLAGS(或EFLAGS)壓入堆棧;
      · 清除TF和IF標(biāo)志位;
      · CS,IP/EIP壓入堆棧;
      · 實(shí)模式下,n×4獲取中斷矢量表地址指針;保護(hù)模式下,n×8獲取中斷描述符表地址指針;
      · 根據(jù)地址指針,從中斷矢量表或中斷描述符表中取出中斷服務(wù)程序地址送IP/EIP和CS中,控制程序轉(zhuǎn)移去執(zhí)行中斷服務(wù)程序。
      中斷返回指令格式:IRET/IRETD
      功能:該指令實(shí)現(xiàn)在中斷服務(wù)程序結(jié)束后,返回到主程序中斷斷點(diǎn)處,繼續(xù)執(zhí)行主程序。
      中斷返回執(zhí)行過(guò)程:
      · IRET指令彈出堆棧中數(shù)據(jù)送IP,CS,F(xiàn)LAGS;
      · IRETD指令彈出堆棧中數(shù)據(jù)送EIP,CS,EFLAGS。
      其它中斷類(lèi)指令如表311所示。

    表 3.11 中斷類(lèi)指令



      二、DOS功能調(diào)用
      系統(tǒng)功能調(diào)用是MS—DOS為程序員編寫(xiě)匯編語(yǔ)言源程序提供的一組子程序,包括設(shè)備管理、文件管理和目錄管理等。
      DOS規(guī)定使用軟中斷指令I(lǐng)NT 21H作為進(jìn)入各功能子程序的總?cè)肟冢贋槊總€(gè)功能調(diào)用規(guī)定一個(gè)功能號(hào),引用功能號(hào)即可進(jìn)入相應(yīng)的子程序入口。DOS系統(tǒng)功能調(diào)用的使用方法歸納如下:
      (1) 傳送入口參數(shù)到指定的寄存器中;
      (2) 把要調(diào)用功能的功能號(hào)送入AH寄存器中;
      (3) 用INT 21H指令轉(zhuǎn)入子程序入口;
      (4) 相應(yīng)的子程序運(yùn)行結(jié)束后,可以按照規(guī)定取得出口參數(shù)。
      常用系統(tǒng)功能調(diào)用簡(jiǎn)介。
      1鍵盤(pán)輸入單字符
      這是1號(hào)系統(tǒng)功能調(diào)用,其調(diào)用格式為
       MOV AH,1
       INT 21H
      該功能調(diào)用無(wú)入口參數(shù)。其功能為系統(tǒng)等待鍵盤(pán)輸入,如是Ctrol-Break鍵則退出;否則將鍵入字符的ASCII碼送入AL寄存器中,并且通過(guò)顯示器顯示該字符。
      2鍵盤(pán)輸入字符串
      這是0AH號(hào)系統(tǒng)功能調(diào)用,其功能為將鍵盤(pán)輸入的字符串寫(xiě)入內(nèi)存單元中。因此,首先在內(nèi)存中定義一個(gè)緩沖區(qū),緩沖區(qū)第一個(gè)字節(jié)存放規(guī)定字符串的最大字 節(jié)數(shù),第二個(gè)字節(jié)由系統(tǒng)送入實(shí)際鍵入的字符數(shù),從第三個(gè)字節(jié)開(kāi)始用于存放鍵入的字符串,最后通過(guò)鍵入回車(chē)鍵來(lái)表示字符串的結(jié)束。如果實(shí)際鍵入的字符數(shù)未達(dá) 到最大規(guī)定數(shù),其緩沖區(qū)的空余區(qū)間填0;如果實(shí)際鍵入數(shù)超過(guò)緩沖區(qū)的容量,則超出的字符自動(dòng)丟失,而且響鈴警告。注意,回車(chē)鍵值也存于緩沖區(qū)中。
      例 3.75 使用格式舉例。
         ·MODEL SMALL
         ·DATA
       BUF  DB 20
          DB?
          DB 20 DUP(?)
         ·CODE
         ·STARTUP
          MOV DX,OFFSET BUF
          MOV AH,0AH
          INT 21H
         ·EXIT
          END
      該程序在BUF為首地址的緩沖區(qū)定義了20個(gè)字符串字節(jié)的緩沖區(qū),并且將緩沖區(qū)首地址送入DX中,調(diào)用0AH號(hào)子程序,系統(tǒng)等待用戶(hù)鍵入字符串,每鍵 入一個(gè)字符,其相應(yīng)的ASCII碼將被寫(xiě)入緩沖區(qū)中,直到鍵入回車(chē)鍵,由系統(tǒng)輸入實(shí)際鍵入字符數(shù),送入緩沖區(qū)第二個(gè)字節(jié)中。
      3輸出單字符
      這是2號(hào)系統(tǒng)功能調(diào)用,其使用格式為:
      MOV DL,‘A’
      MOV AH,2
      INT 21H
      執(zhí)行2號(hào)系統(tǒng)功能調(diào)用,將置入DL寄存器中的字符(以ASCII碼形式表示)通過(guò)顯示器顯示出來(lái)(或從打印機(jī)輸出)。
      4輸出字符串
      這是9號(hào)系統(tǒng)功能調(diào)用,其功能是將指定的內(nèi)存緩沖區(qū)中的字符串從顯示器顯示輸出(或從打印機(jī)輸出),緩沖區(qū)中的字符串以字符‘$’作為結(jié)束標(biāo)志。
      例 3.76使用格式舉例。
        ·MODEL SMALL
        ·DATA
      BUF DB ‘Thank you $’
        ·CODE
        ·STARTUP
         MOV DX,OFFSET BUF
         MOV AH,9
         INT 21H
        ·EXIT
         END
      5返回操作系統(tǒng)
      這是4CH號(hào)系統(tǒng)功能調(diào)用,使用格式為
      MOV AH,4CH
      INT 21H
      在用戶(hù)程序結(jié)束處插入此調(diào)用,則返回到DOS操作系統(tǒng),顯示器顯示系統(tǒng)提示符。
    習(xí)題與思考題
    1數(shù)據(jù)尋址方式有哪幾種?
    216位指令模式下和32位指令模式下的存儲(chǔ)器尋址方式各有哪幾種尋址方式?并比較它們相似與不同之處。
    3程序地址尋址方式有哪幾種?
    4什么是堆棧地址尋址方式?
    5指令編碼格式是由哪幾部分組成的?各部分的含義是什么?
    6 80x86的指令格式由哪幾部分組成?
    7 80x86指令系統(tǒng)按其功能可分為幾部分?
    8數(shù)據(jù)傳送指令包括哪些類(lèi)型?
    9堆棧的含義是什么?80x86所用的堆棧有什么特點(diǎn)?
    10堆棧操作指令有哪幾種?
    11 XLAT指令在使用時(shí)有哪些規(guī)定?
    12符號(hào)擴(kuò)展指令在什么情況下使用?
    13十進(jìn)制算術(shù)運(yùn)算調(diào)整指令在什么情況下使用?它們都是跟在哪些指令的后面?
    14哪些指令采用隱含尋址?
    15使用算術(shù)運(yùn)算類(lèi)指令應(yīng)注意哪些問(wèn)題?
    16邏輯運(yùn)算指令有幾種?
    17測(cè)試指令和比較指令在使用時(shí)有什么不同?
    18算術(shù)移位指令和邏輯移位指令有什么不同?
    19控制轉(zhuǎn)移類(lèi)指令的作用是什么?有哪幾種?
    20什么叫串?串操作指令有哪些?串前綴在什么情況下使用?
    21輸入/輸出指令起什么作用?尋址方式有哪些?
    22設(shè)DS=2000H,SS=3000H,BP=0200H,SI=4000H,BUF=1000H,EAX=00001000H,EBX= 00002000H,假設(shè)按16位實(shí)模式操作,確定下列每條指令訪問(wèn)內(nèi)存的物理地址,并且指出源操作數(shù)及目的操作數(shù)的尋址方式。
    (1) MOV AL,[1234H](2) MOV EDX,[BX]
    (3) MOV CL,[BX+100H](4) MOV [SI],EBX
    (5) MOV AH,BUF[BX+SI](6) MOV EAX,[BP+1234H]
    (7) MOV [EAX+EBX],DH
    23試指出下列指令中的錯(cuò)誤。
    (1) MOV [BX],[SI](2) MOV AH,DX
    (3) INC [BX](4) MOV DS,SS
    (5) XCHG AX,2000H(6) MOV AX,[BX+DX]
    (7) XCHG [SP],ES(8) ADD [AX],BX
    (9) MOV AX,DI+SI(10) INAL,BX
    24指出下列算術(shù)邏輯指令執(zhí)行后標(biāo)志CF,ZF,SF,PF,OF和AF的狀態(tài)。
    MOV AL,80H
    DEC AL
    ADD AL,10H
    SUB AL,10H
    MOV AL,3AH
    AND AL,0F0H
    OR AL,0F0H
    XOR AL,0F0H
    25使AX寄存器清0有多種方式,試寫(xiě)出這多條指令。
    26寫(xiě)出把首地址為BUF的字節(jié)緩沖區(qū)中第5個(gè)字節(jié)數(shù)送AL寄存器的指令,要求使用以下幾種尋址方式:
    (1) 寄存器間接尋址;
    (2) 寄存器相對(duì)尋址;
    (3) 基址變址尋址。
    27試分別使用數(shù)據(jù)傳送指令、交換指令和堆棧操作指令,實(shí)現(xiàn)將首地址為BLOCK的內(nèi)存單元中兩個(gè)數(shù)據(jù)字交換。BLOCK變量定義如下:
    BLOCK DW 10H,20H
    28設(shè)一個(gè)字節(jié)數(shù)據(jù)X存放在AL寄存器中,試說(shuō)明下列程序的功能。
    XOR AH,AH
    SAL AX,1
    MOV BX,AX
    MOV CL,2
    SAL AX,CL
    ADD AX,BX
    29試編程實(shí)現(xiàn):
    (1) AL寄存器的低4位清0;
    (2) BL寄存器的低4位置1;
    (3) CL寄存器的低4位取反;
    (4) 測(cè)試DL寄存器的最低2位是否為0,若是將0送入AL寄存器;否則將1送AL寄存器。
    30試編程統(tǒng)計(jì)在AX寄存器中有多少個(gè)1,并將結(jié)果送DL寄存器中。
    31試編程統(tǒng)計(jì)在內(nèi)存BLOCK單元開(kāi)始按字節(jié)存放的100個(gè)帶符號(hào)數(shù)中有多少負(fù)數(shù),并將結(jié)果存放在DL寄存器中。



================================================================

 32位CPU所含有的寄存器有:

4個(gè)數(shù)據(jù)寄存器(EAX、EBX、ECX和EDX)
2個(gè)變址和指針寄存器(ESI和EDI) 2個(gè)指針寄存器(ESP和EBP)
6個(gè)段寄存器(ES、CS、SS、DS、FS和GS)
1個(gè)指令指針寄存器(EIP) 1個(gè)標(biāo)志寄存器(EFlags)

1、數(shù)據(jù)寄存器

數(shù)據(jù)寄存器主要用來(lái)保存操作數(shù)和運(yùn)算結(jié)果等信息,從而節(jié)省讀取操作數(shù)所需占用總線和訪問(wèn)存儲(chǔ)器的時(shí)間。

32位CPU有4個(gè)32位的通用寄存器EAX、EBX、ECX和EDX。對(duì)低16位數(shù)據(jù)的存取,不會(huì)影響高16位的數(shù)據(jù)。這些
低16位寄存器分別命名為:AX、BX、CX和DX,它和先前的CPU中的寄存器相一致。

4個(gè)16位寄存器又可分割成8個(gè)獨(dú)立的8位寄存器(AX:AH-AL、BX:BH-BL、CX:CH-CL、DX:DH-DL),每個(gè)寄
存器都有自己的名稱(chēng),可獨(dú)立存取。程序員可利用數(shù)據(jù)寄存器的這種“可分可合”的特性,靈活地處理字/字
節(jié)的信息。

AX和AL通常稱(chēng)為累加器(Accumulator):可用于乘、除、輸入/輸出等操作(在乘除指令中指定用來(lái)存放操作數(shù))
BX稱(chēng)為基地址寄存器(Base Register):在計(jì)算存儲(chǔ)器地址時(shí),可作為基址寄存器使用。
CX稱(chēng)為計(jì)數(shù)寄存器(Count Register):用來(lái)保存計(jì)數(shù)值,如在移位指令、循環(huán)指令和串處理指令中用作隱含的計(jì)數(shù)器(當(dāng)移多位時(shí),要用CL來(lái)指明移位的位數(shù))。DX在作雙字長(zhǎng)運(yùn)算時(shí),可把DX和AX組合在一起存放一個(gè)雙字長(zhǎng)數(shù),DX用來(lái)存放高16位數(shù)據(jù)。此外,對(duì)某些I/O操作,DX可用來(lái)存放I/O的端口地址。
DX稱(chēng)為數(shù)據(jù)寄存器(Data Register)。在進(jìn)行乘、除運(yùn)算時(shí),它可作為默認(rèn)的操作數(shù)參與運(yùn)算,也可用于存放I/O的端口地址。

在16位CPU中,AX、BX、CX和DX不能作為基址和變址寄存器來(lái)存放存儲(chǔ)單元的地址,但在32位CPU中,其32位
寄存器EAX、EBX、ECX和EDX不僅可傳送數(shù)據(jù)、暫存數(shù)據(jù)保存算術(shù)邏輯運(yùn)算結(jié)果,而且也可作為指針寄存器,
所以,這些32位寄存器更具有通用性。

2、變址寄存器

32位CPU有2個(gè)32位通用寄存器ESI和EDI。其低16位對(duì)應(yīng)先前CPU中的SI和DI,對(duì)低16位數(shù)據(jù)的存取,不影響
高16位的數(shù)據(jù)。

寄存器ESI、EDI、SI和DI稱(chēng)為變址寄存器(Index Register),它們主要用于存放存儲(chǔ)單元在段內(nèi)的偏移量,
用它們可實(shí)現(xiàn)多種存儲(chǔ)器操作數(shù)的尋址方式,為以不同的地址形式訪問(wèn)存儲(chǔ)單元提供方便。

變址寄存器不可分割成8位寄存器。作為通用寄存器,也可存儲(chǔ)算術(shù)邏輯運(yùn)算的操作數(shù)和運(yùn)算結(jié)果。

它們可作一般的存儲(chǔ)器指針使用。在字符串操作指令的執(zhí)行過(guò)程中,對(duì)它們有特定的要求,而且還具有特
殊的功能。

3、指針寄存器

32位CPU有2個(gè)32位通用寄存器EBP和ESP。其低16位對(duì)應(yīng)先前CPU中的SBP和SP,對(duì)低16位數(shù)據(jù)的存取,不影
響高16位的數(shù)據(jù)。

寄存器EBP、ESP、BP和SP稱(chēng)為指針寄存器(Pointer Register),主要用于存放堆棧內(nèi)存儲(chǔ)單元的偏移量,
用它們可實(shí)現(xiàn)多種存儲(chǔ)器操作數(shù)的尋址方式,為以不同的地址形式訪問(wèn)存儲(chǔ)單元提供方便。

指針寄存器不可分割成8位寄存器。作為通用寄存器,也可存儲(chǔ)算術(shù)邏輯運(yùn)算的操作數(shù)和運(yùn)算結(jié)果。

它們主要用于訪問(wèn)堆棧內(nèi)的存儲(chǔ)單元,并且規(guī)定:

BP為基指針(Base Pointer)寄存器,用它可直接存取堆棧中的數(shù)據(jù);
SP為堆棧指針(Stack Pointer)寄存器,用它只可訪問(wèn)棧頂。

4、段寄存器

段寄存器是根據(jù)內(nèi)存分段的管理模式而設(shè)置的。內(nèi)存單元的物理地址由段寄存器的值和一個(gè)偏移量組合而成
的,這樣可用兩個(gè)較少位數(shù)的值組合成一個(gè)可訪問(wèn)較大物理空間的內(nèi)存地址。

CPU內(nèi)部的段寄存器:

CS——代碼段寄存器(Code Segment Register),其值為代碼段的段值;
DS——數(shù)據(jù)段寄存器(Data Segment Register),其值為數(shù)據(jù)段的段值;
ES——附加段寄存器(Extra Segment Register),其值為附加數(shù)據(jù)段的段值;
SS——堆棧段寄存器(Stack Segment Register),其值為堆棧段的段值;
FS——附加段寄存器(Extra Segment Register),其值為附加數(shù)據(jù)段的段值;
GS——附加段寄存器(Extra Segment Register),其值為附加數(shù)據(jù)段的段值。

在16位CPU系統(tǒng)中,它只有4個(gè)段寄存器,所以,程序在任何時(shí)刻至多有4個(gè)正在使用的段可直接訪問(wèn);在32位
微機(jī)系統(tǒng)中,它有6個(gè)段寄存器,所以,在此環(huán)境下開(kāi)發(fā)的程序最多可同時(shí)訪問(wèn)6個(gè)段。

32位CPU有兩個(gè)不同的工作方式:實(shí)方式和保護(hù)方式。在每種方式下,段寄存器的作用是不同的。有關(guān)規(guī)定簡(jiǎn)
單描述如下:
實(shí)方式: 前4個(gè)段寄存器CS、DS、ES和SS與先前CPU中的所對(duì)應(yīng)的段寄存器的含義完全一致,內(nèi)存單元的邏輯
地址仍為“段值:偏移量”的形式。為訪問(wèn)某內(nèi)存段內(nèi)的數(shù)據(jù),必須使用該段寄存器和存儲(chǔ)單元的偏移量。
保護(hù)方式: 在此方式下,情況要復(fù)雜得多,裝入段寄存器的不再是段值,而是稱(chēng)為“選擇子”(Selector)的某個(gè)值。。

5、指令指針寄存器

32位CPU把指令指針擴(kuò)展到32位,并記作EIP,EIP的低16位與先前CPU中的IP作用相同。

指令指針EIP、IP(Instruction Pointer)是存放下次將要執(zhí)行的指令在代碼段的偏移量。在具有預(yù)取指令功
能的系統(tǒng)中,下次要執(zhí)行的指令通常已被預(yù)取到指令隊(duì)列中,除非發(fā)生轉(zhuǎn)移情況。所以,在理解它們的功能
時(shí),不考慮存在指令隊(duì)列的情況。

在實(shí)方式下,由于每個(gè)段的最大范圍為64K,所以,EIP中的高16位肯定都為0,此時(shí),相當(dāng)于只用其低16位
的IP來(lái)反映程序中指令的執(zhí)行次序。

6、標(biāo)志寄存器

一、運(yùn)算結(jié)果標(biāo)志位
1、進(jìn)位標(biāo)志CF(Carry Flag)
進(jìn)位標(biāo)志CF主要用來(lái)反映運(yùn)算是否產(chǎn)生進(jìn)位或借位。如果運(yùn)算結(jié)果的最高位產(chǎn)生了一個(gè)進(jìn)位或借位,那么,其值為1,否則其值為0。

使用該標(biāo)志位的情況有:多字(字節(jié))數(shù)的加減運(yùn)算,無(wú)符號(hào)數(shù)的大小比較運(yùn)算,移位操作,字(字節(jié))之間移位,專(zhuān)門(mén)改變CF值的指令等。

2、奇偶標(biāo)志PF(Parity Flag)
奇偶標(biāo)志PF用于反映運(yùn)算結(jié)果中“1”的個(gè)數(shù)的奇偶性。如果“1”的個(gè)數(shù)為偶數(shù),則PF的值為1,否則其值為0。

利用PF可進(jìn)行奇偶校驗(yàn)檢查,或產(chǎn)生奇偶校驗(yàn)位。在數(shù)據(jù)傳送過(guò)程中,為了提供傳送的可靠性,如果采用奇偶校驗(yàn)的方法,就可使用該標(biāo)志位。

3、輔助進(jìn)位標(biāo)志AF(Auxiliary Carry Flag)
在發(fā)生下列情況時(shí),輔助進(jìn)位標(biāo)志AF的值被置為1,否則其值為0:

(1)、在字操作時(shí),發(fā)生低字節(jié)向高字節(jié)進(jìn)位或借位時(shí);
(2)、在字節(jié)操作時(shí),發(fā)生低4位向高4位進(jìn)位或借位時(shí)。

對(duì)以上6個(gè)運(yùn)算結(jié)果標(biāo)志位,在一般編程情況下,標(biāo)志位CF、ZF、SF和OF的使用頻率較高,而標(biāo)志位PF和AF的使用頻率較低。

4、零標(biāo)志ZF(Zero Flag)
零標(biāo)志ZF用來(lái)反映運(yùn)算結(jié)果是否為0。如果運(yùn)算結(jié)果為0,則其值為1,否則其值為0。在判斷運(yùn)算結(jié)果是否為0時(shí),可使用此標(biāo)志位。

5、符號(hào)標(biāo)志SF(Sign Flag)
符號(hào)標(biāo)志SF用來(lái)反映運(yùn)算結(jié)果的符號(hào)位,它與運(yùn)算結(jié)果的最高位相同。在微機(jī)系統(tǒng)中,有符號(hào)數(shù)采用補(bǔ)碼表示法,所以,SF也就反映運(yùn)算結(jié)果的正負(fù)號(hào)。運(yùn)算結(jié)果為正數(shù)時(shí),SF的值為0,否則其值為1。

6、溢出標(biāo)志OF(Overflow Flag)
溢出標(biāo)志OF用于反映有符號(hào)數(shù)加減運(yùn)算所得結(jié)果是否溢出。如果運(yùn)算結(jié)果超過(guò)當(dāng)前運(yùn)算位數(shù)所能表示的范圍,則稱(chēng)為溢出,OF的值被置為1,否則,OF的值被清為0。

“溢出”和“進(jìn)位”是兩個(gè)不同含義的概念,不要混淆。如果不太清楚的話,請(qǐng)查閱《計(jì)算機(jī)組成原理》課程中的有關(guān)章節(jié)。

二、狀態(tài)控制標(biāo)志位
狀態(tài)控制標(biāo)志位是用來(lái)控制CPU操作的,它們要通過(guò)專(zhuān)門(mén)的指令才能使之發(fā)生改變。

1、追蹤標(biāo)志TF(Trap Flag)
當(dāng)追蹤標(biāo)志TF被置為1時(shí),CPU進(jìn)入單步執(zhí)行方式,即每執(zhí)行一條指令,產(chǎn)生一個(gè)單步中斷請(qǐng)求。這種方式主要用于程序的調(diào)試。

指令系統(tǒng)中沒(méi)有專(zhuān)門(mén)的指令來(lái)改變標(biāo)志位TF的值,但程序員可用其它辦法來(lái)改變其值。

2、中斷允許標(biāo)志IF(Interrupt-enable Flag)
中斷允許標(biāo)志IF是用來(lái)決定CPU是否響應(yīng)CPU外部的可屏蔽中斷發(fā)出的中斷請(qǐng)求。但不管該標(biāo)志為何值,CPU都必須響應(yīng)CPU外部的不可屏蔽中斷所發(fā)出的中斷請(qǐng)求,以及CPU內(nèi)部產(chǎn)生的中斷請(qǐng)求。具體規(guī)定如下:

(1)、當(dāng)IF=1時(shí),CPU可以響應(yīng)CPU外部的可屏蔽中斷發(fā)出的中斷請(qǐng)求;

(2)、當(dāng)IF=0時(shí),CPU不響應(yīng)CPU外部的可屏蔽中斷發(fā)出的中斷請(qǐng)求。

CPU的指令系統(tǒng)中也有專(zhuān)門(mén)的指令來(lái)改變標(biāo)志位IF的值。

3、方向標(biāo)志DF(Direction Flag)
方向標(biāo)志DF用來(lái)決定在串操作指令執(zhí)行時(shí)有關(guān)指針寄存器發(fā)生調(diào)整的方向。具體規(guī)定在第5.2.11節(jié)——字符串操作指令——中給出。在微機(jī)的指令系統(tǒng)中,還提供了專(zhuān)門(mén)的指令來(lái)改變標(biāo)志位DF的值。

三、32位標(biāo)志寄存器增加的標(biāo)志位
1、I/O特權(quán)標(biāo)志IOPL(I/O Privilege Level)
I/O特權(quán)標(biāo)志用兩位二進(jìn)制位來(lái)表示,也稱(chēng)為I/O特權(quán)級(jí)字段。該字段指定了要求執(zhí)行I/O指令的特權(quán)級(jí)。如果當(dāng)前的特權(quán)級(jí)別在數(shù)值上小于等于IOPL的值,那么,該I/O指令可執(zhí)行,否則將發(fā)生一個(gè)保護(hù)異常。

2、嵌套任務(wù)標(biāo)志NT(Nested Task)
嵌套任務(wù)標(biāo)志NT用來(lái)控制中斷返回指令I(lǐng)RET的執(zhí)行。具體規(guī)定如下:

(1)、當(dāng)NT=0,用堆棧中保存的值恢復(fù)EFLAGS、CS和EIP,執(zhí)行常規(guī)的中斷返回操作;

(2)、當(dāng)NT=1,通過(guò)任務(wù)轉(zhuǎn)換實(shí)現(xiàn)中斷返回。

3、重啟動(dòng)標(biāo)志RF(Restart Flag)
重啟動(dòng)標(biāo)志RF用來(lái)控制是否接受調(diào)試故障。規(guī)定:RF=0時(shí),表示“接受”調(diào)試故障,否則拒絕之。在成功執(zhí)行完一條指令后,處理機(jī)把RF置為0,當(dāng)接受到一個(gè)非調(diào)試故障時(shí),處理機(jī)就把它置為1,中國(guó)自學(xué)編程網(wǎng)整理發(fā)布!。

4、虛擬8086方式標(biāo)志VM(Virtual 8086 Mode)
如果該標(biāo)志的值為1,則表示處理機(jī)處于虛擬的8086方式下的工作狀態(tài),否則,處理機(jī)處于一般保護(hù)方式下的工作狀態(tài)。


===================================================

雖然jmp指令提供了控制轉(zhuǎn)移,但是它不允許進(jìn)行任何復(fù)雜的判斷。80x86條件跳轉(zhuǎn)指令提供了這種判斷。條件跳轉(zhuǎn)指令是創(chuàng)建循環(huán)和實(shí)現(xiàn)其他條件執(zhí)行語(yǔ)句,如if…endif的基本要素。

條件跳轉(zhuǎn)指令檢查一個(gè)或多個(gè)標(biāo)志位,判斷它們是否匹配某個(gè)特殊條件(就像setcc指令):如果標(biāo)志匹配成功,該指令就將控制轉(zhuǎn)移到目標(biāo)位置;如果匹配失敗,CPU忽略該條件跳轉(zhuǎn)指令而繼續(xù)執(zhí)行下一條指令。一些條件跳轉(zhuǎn)指令只是簡(jiǎn)單測(cè)試符號(hào)位(sign)、進(jìn)位位(carry)、溢出位(overflow)、零標(biāo)志(zero)位的設(shè)置。例如,在執(zhí)行一條sh1指令后,您需要測(cè)試進(jìn)位標(biāo)志,來(lái)判斷sh1是否從操作數(shù)的高地址位移出一位。類(lèi)似地,也可以在一條test指令后測(cè)試零標(biāo)志位,來(lái)判斷指定的位是否為1。大多數(shù)情況,在cmp指令之后執(zhí)行條件跳轉(zhuǎn)指令。cmp指令設(shè)置標(biāo)志位,以便判斷小于、大于、等于等情況。
條件跳轉(zhuǎn)指令形式如下:
Jcc label;
其中,Jcc中的“cc”,必須用表示測(cè)試條件類(lèi)型的字符序列替換。這些字符和setcc指令使用的一樣。例如,“js”表示根據(jù)符號(hào)(sign)標(biāo)志是否被置位來(lái)決定是否跳轉(zhuǎn)。一個(gè)典型的js指令如下:
js ValueIsNegative ;
在這個(gè)示例中,如果符號(hào)(sign)標(biāo)志被置位,則js指令將控制轉(zhuǎn)移到ValueIsNegative語(yǔ)句標(biāo)號(hào)處;如果符號(hào)標(biāo)志清零,則將控制直接轉(zhuǎn)移給js指令后的指令。
與無(wú)條件jmp指令不同,條件跳轉(zhuǎn)指令不提供間接跳轉(zhuǎn)的形式。惟一允許的形式是跳轉(zhuǎn)到程序中某一標(biāo)號(hào)處。條件跳轉(zhuǎn)指令有一個(gè)限制:目標(biāo)標(biāo)號(hào)的位置必須在跳轉(zhuǎn)指令本身附近32768字節(jié)范圍內(nèi),這通常對(duì)應(yīng)著8000~32000條機(jī)器指令。一般情況下不會(huì)超過(guò)這種限制。
注意:Intel文檔為許多條件跳轉(zhuǎn)指令定義了多種替代名或指令別名。表7-1、7-2和7-3列出了每個(gè)指令所有的別名。這些表格也列出了表示相反分支的指令。很快您將明白這些相反分支指令的作用。
表7-1 測(cè)試標(biāo)志位的JCC指令
指 令
描 述
條 件
別 名
相 反 指 令
JC
如果進(jìn)位位被置位則跳轉(zhuǎn)
進(jìn)位標(biāo)志=1
JB,JNAE
JNC
JNC
如果進(jìn)位位沒(méi)有置位則跳轉(zhuǎn)
進(jìn)位標(biāo)志=0
JNB,JAE
JC
JZ
如果0標(biāo)志被置位則跳轉(zhuǎn)
0標(biāo)志=1
JE
JNZ
JNZ
如果0標(biāo)志沒(méi)有置位則跳轉(zhuǎn)
0標(biāo)志=0
JNE
JZ
(續(xù)表)
指 令
描 述
條 件
別 名
相反指令
JS
如果符號(hào)位被置位則跳轉(zhuǎn)
符號(hào)標(biāo)志=1
 
JNS
JNS
如果符號(hào)位沒(méi)有被置位則跳轉(zhuǎn)
符號(hào)標(biāo)志=0
 
JS
JO
如果溢出標(biāo)志置位則跳轉(zhuǎn)
溢出標(biāo)志=1
 
JNO
JNO
如果溢出標(biāo)志沒(méi)有置位則跳轉(zhuǎn)
溢出標(biāo)志=0
JO
 
JP
如果奇偶校驗(yàn)位被置位則跳轉(zhuǎn)
奇偶校驗(yàn)標(biāo)志=1
JPE
JNP
JPE
如果奇偶校驗(yàn)位為偶校驗(yàn)則跳轉(zhuǎn)
奇偶校驗(yàn)標(biāo)志=1
JP
JPO
JNP
如果奇偶校驗(yàn)位沒(méi)有被置位則跳轉(zhuǎn)
奇偶校驗(yàn)標(biāo)志=0
JPO
JP
JPO
如果奇偶校驗(yàn)位為奇校驗(yàn)則跳轉(zhuǎn)
奇偶校驗(yàn)標(biāo)志=0
JNP
JPE
表7-2 使用無(wú)符號(hào)數(shù)比較的JCC指令
指 令
描 述
條 件
別 名
相反指令
JA
如果超過(guò)(>)則跳轉(zhuǎn)
進(jìn)位標(biāo)志=0,0標(biāo)志=0
JNBE
JNA
JNBE
如果不低于或等于(不 <=)則跳轉(zhuǎn)
進(jìn)位標(biāo)志=0,0標(biāo)志=0
JA
JBE
JAE
如果超過(guò)或等于(>=)則跳轉(zhuǎn)
進(jìn)位標(biāo)志=0
JNC,JNB
JNAE
JNB
如果不低于則跳轉(zhuǎn)(不 <)
進(jìn)位標(biāo)志=0
JNC,JAE
JB
JB
如果低于(<)則跳轉(zhuǎn)
進(jìn)位標(biāo)志=1
JC,JNAE
JNB
JNAE
如果不超過(guò)或等于(不>=)則跳轉(zhuǎn)
進(jìn)位標(biāo)志=1
JC,JB
JAE
JBE
如果低于或等于(<=)則跳轉(zhuǎn)
進(jìn)位標(biāo)志=1或0標(biāo)志=1
JNA
JNBE
JNA
如果不超過(guò)(不>)則跳轉(zhuǎn)
進(jìn)位標(biāo)志=1或0標(biāo)志=1
JBE
JA
JE
如果相等(=)則跳轉(zhuǎn)
0標(biāo)志=1
JZ
JNE
JNE
如果不相等(<>)則跳轉(zhuǎn)
0標(biāo)志=0
JNZ
JE
表7-3 使用有符號(hào)數(shù)比較的JCC指令
指 令
描 述
條 件
別 名
相反指令
JG
如果大于(>)則跳轉(zhuǎn)
符號(hào)標(biāo)志=溢出標(biāo)志或0標(biāo)志=0
JNLE
JNG
JNLE
如果小于或等于(<=)則跳轉(zhuǎn)
符號(hào)標(biāo)志=溢出標(biāo)志或0標(biāo)志=0
JG
JLE
JGE
如果大于或等于(>=)則跳轉(zhuǎn)
符號(hào)標(biāo)志=溢出標(biāo)志
JNL
JGE
JNL
如果不小于(不<)則跳轉(zhuǎn)
符號(hào)標(biāo)志=溢出標(biāo)志
JGE
JL
JL
如果小于(<)則跳轉(zhuǎn)
符號(hào)標(biāo)志<>溢出標(biāo)志
JNGE
JNL
JNGE
如果大于或等于(>=)跳轉(zhuǎn)
符號(hào)標(biāo)志<>溢出標(biāo)志
JL
JGE
JLE
如果小于或等于(<=)跳轉(zhuǎn)
符號(hào)標(biāo)志<>溢出標(biāo)志或0標(biāo)志=1
JNG
JNLE
JNG
如果不大于(不>)則跳轉(zhuǎn)
符號(hào)標(biāo)志<>溢出標(biāo)志或0標(biāo)志=1
JLE
JG
JE
如果等于(=)則跳轉(zhuǎn)
0標(biāo)志=1
JZ
JNE
JNE
如果不等于(<>)則跳轉(zhuǎn)
0標(biāo)志=0
JNZ
JE
接下來(lái)將對(duì)“相反指令”一列進(jìn)行簡(jiǎn)單的說(shuō)明。在許多情況下,需要產(chǎn)生與某條分支指令條件相反的分支(在本章后面會(huì)給出示例),即相反分支。除了兩個(gè)例外,都可以按下面的簡(jiǎn)單規(guī)則(后面統(tǒng)稱(chēng)為N/No N規(guī)則)產(chǎn)生相反分支:
● 如果Jcc的第二個(gè)字母不是“n”,則在“j”后面插入一個(gè)“n”。例如:je對(duì)應(yīng)為jne,jl對(duì)應(yīng)為jnl。
● 如果Jcc的第二個(gè)字母是“n”,則去掉指令中的“n”。例如:jng對(duì)應(yīng)為jg,jne對(duì)應(yīng)為je。
不遵循這兩條規(guī)則的兩個(gè)例外是jpe(奇偶位為偶跳轉(zhuǎn))和jpo(奇偶位為奇跳轉(zhuǎn))。這兩個(gè)例外并不會(huì)導(dǎo)致什么問(wèn)題,因?yàn)椋?a)很少需要測(cè)試奇偶標(biāo)志;(b)可以使用別名jp和jnp替代jpe和jpo。而“N/No N”規(guī)則對(duì)jp和jnp是適用的。
雖然jge是jl的相反指令,但是建議使用jnl作為jl的相反指令。因?yàn)楹苋菀渍`認(rèn)為“大于是小于的相反”,從而把jg當(dāng)作jl的相反指令。您可以堅(jiān)持使用“N/No N”規(guī)則以避免這種混淆。
80x86條件跳轉(zhuǎn)指令提供了這樣的能力:根據(jù)判斷條件將程序流分支到兩條路徑中的某一條。例如,要實(shí)現(xiàn):如果BX等于CX,則寄存器AX的值加1??梢允褂孟旅娴拇a來(lái)完成該功能:
cmp(bx,cx );
jne SkipStmts;
inc(ax );
SkipStmts:
其中的訣竅是使用相反分支指令來(lái)跳過(guò)在條件滿(mǎn)足的情況下需要執(zhí)行的指令。請(qǐng)堅(jiān)持使用前面介紹的“N/no N”規(guī)則來(lái)選擇相反分支指令。
使用條件跳轉(zhuǎn)指令還可以實(shí)現(xiàn)循環(huán)。例如,下面的代碼序列實(shí)現(xiàn)了從用戶(hù)輸入讀入一串字符,并將字符存儲(chǔ)到一組連續(xù)的單元中,直到用戶(hù)輸入回車(chē)鍵。
   mov(0,edi );
RdLnLoop:
  stdin.getc(); //Read a character into the AL register.
   mov(al,Input [edi])); //Store away the character.
   inc(edi ); //Move on to the next character.
   cmp(al,stdio.cr ); //See if the user pressed Enter.
   jne RdLnLoop;
與setcc指令類(lèi)似,條件跳轉(zhuǎn)指令分為兩類(lèi)—— 測(cè)試特殊處理器標(biāo)志位的條件跳轉(zhuǎn)指令(例如jz、jc、jno)和測(cè)試某些條件(小于、大于等)的條件跳轉(zhuǎn)指令。當(dāng)測(cè)試某個(gè)條件時(shí),條件跳轉(zhuǎn)指令通常緊跟在一個(gè)cmp指令之后。cmp指令設(shè)置標(biāo)志位后,如果是無(wú)符號(hào)數(shù)比較,使用ja、jae、jb、jbe、je或jne等指令測(cè)試這些標(biāo)志來(lái)判斷是否小于、小于等于、等于、不等于、大于或大于等于;如果是有符號(hào)數(shù)比較,則使用jl、jle、je、jne、jg、jge指令。
條件跳轉(zhuǎn)指令測(cè)試標(biāo)志位,但不影響標(biāo)志位。


=========================


jnz(jump if not zero flag set) 和 jne(jump if not equal) 有相同的功效。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶(hù)發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶(hù) 評(píng)論公約

    類(lèi)似文章 更多