学习汇编记录Day3——汇编指令

在了解了寄存器和寻址方式后,汇编最吸引人的不就是指令么?

哈哈哈,我就是奔着指令来的其实。

指令分类:总共13种方法。

数据传送指令,标志位操作指令,算术运算指令,逻辑运算指令,  (这些应该算是基本指令)

移位操作指令,位操作指令,比较运算指令

印象:mov, xchg, lea, lds, les, push, pop, clc, cmc, stc, cld, std, cli, sti

                  sahf, lahf, pushf, popf, add, inc, adc,  sub, sbb, dec, neg, mul, imul

                  div, idiv, cbw, cwd, cwde, cdq,  and, or, not, xor,  sal, sar,  shl, shr, shld, shlr, rol, ror, rcl, rcr

                   bsf, bsr, bt, test

循环指令,转移指令条件设置字节指令

loop...         jmp               setnn      ;  80386后新添加的指令

字符串操作指令,

比如movs, s是string的意思

ASCII-BCD码运算调整指令,处理器指令(这两种不常用)。

一,寄存器中的标志寄存器。

一、运算结果标志位

1、进位标志CF(Carry Flag)

进位标志CF主要用来反映运算是否产生进位或借位。如果运算结果的最高位产生了一个进位或借位,那么,其值为1,否则其值为0。

使用该标志位的情况有:多字(字节)数的加减运算,无符号数的大小比较运算,移位操作,字(字节)之间移位,专门改变CF值的指令等。

2、奇偶标志PF(Parity Flag)

奇偶标志PF用于反映运算结果中“1”的个数的奇偶性。如果“1”的个数为偶数,则PF的值为1,否则其值为0。

利用PF可进行奇偶校验检查,或产生奇偶校验位。在数据传送过程中,为了提供传送的可靠性,如果采用奇偶校验的方法,就可使用该标志位。

3、辅助进位标志AF(Auxiliary Carry Flag)

在发生下列情况时,辅助进位标志AF的值被置为1,否则其值为0:

(1)、在字操作时,发生低字节向高字节进位或借位时;
(2)、在字节操作时,发生低4位向高4位进位或借位时。

对以上6个运算结果标志位,在一般编程情况下,标志位CF、ZF、SF和OF的使用频率较高,而标志位PF和AF的使用频率较低。

4、零标志ZF(Zero Flag)

零标志ZF用来反映运算结果是否为0。如果运算结果为0,则其值为1,否则其值为0。在判断运算结果是否为0时,可使用此标志位。

5、符号标志SF(Sign Flag)

符号标志SF用来反映运算结果的符号位,它与运算结果的最高位相同。在微机系统中,有符号数采用补码表示法,所以,SF也就反映运算结果的正负号。运算结果为正数时,SF的值为0,否则其值为1。

6、溢出标志OF(Overflow Flag)

溢出标志OF用于反映有符号数加减运算所得结果是否溢出。如果运算结果超过当前运算位数所能表示的范围,则称为溢出,OF的值被置为1,否则,OF的值被清为0。

“溢出”和“进位”是两个不同含义的概念,不要混淆。如果不太清楚的话,请查阅《计算机组成原理》课程中的有关章节。

二、状态控制标志位

状态控制标志位是用来控制CPU操作的,它们要通过专门的指令才能使之发生改变。

1、追踪标志TF(Trap Flag)

当追踪标志TF被置为1时,CPU进入单步执行方式,即每执行一条指令,产生一个单步中断请求。这种方式主要用于程序的调试。

指令系统中没有专门的指令来改变标志位TF的值,但程序员可用其它办法来改变其值。

2、中断允许标志IF(Interrupt-enable Flag)

中断允许标志IF是用来决定CPU是否响应CPU外部的可屏蔽中断发出的中断请求。但不管该标志为何值,CPU都必须响应CPU外部的不可屏蔽中断所发出的中断请求,以及CPU内部产生的中断请求。具体规定如下:

(1)、当IF=1时,CPU可以响应CPU外部的可屏蔽中断发出的中断请求;

(2)、当IF=0时,CPU不响应CPU外部的可屏蔽中断发出的中断请求。

CPU的指令系统中也有专门的指令来改变标志位IF的值。

3、方向标志DF(Direction Flag)

方向标志DF用来决定在串操作指令执行时有关指针寄存器发生调整的方向。具体规定在第5.2.11节——字符串操作指令——中给出。在微机的指令系统中,还提供了专门的指令来改变标志位DF的值。

问题:

二,指令系统

    指令格式:

                       指令助忆符             [操作数1 [, 操作数2 [, 操作数3]]]   [;注释

          遵守:指令助记符和操作数之间要有分隔符, 分隔符可以是空格和 tab键;

                      如果指令包含多个操作数,那么,操作数之间用逗号分开。

          掌握:要求指令操作数的寻址方式。

                      指令对标志位的影响、标志位对指令的影响;

                      指令的执行时间,对可完成同样功能的指令,要选用执行时间短的指令。

(reg = register 寄存器。   mem = memory 存储器, imm = immediate 立即数)

1、数据传送指令(除标志位操作指令外,都不影响标志位)

1.1、传送指令

         MOV  Reg/Mem,  Reg/Mem/Imm

       

指令的语法

举例

周期数

MOV reg,reg

mov bp,sp

1

MOV mem,reg

mov array[di],bx

1

MOV reg,mem

mov bx,pointer

1

MOV mem,immed

mov [bx],15

1

MOV reg,immed

mov cx,256

1

MOV mem,accum

mov total,ax

1

MOV accum,mem

mov al,string

1

MOV segreg,reg16

mov ds,ax

2, 3

MOV segreg,mem16

mov es,psp

2, 3

MOV reg16,segreg

mov ax,ds

1

MOV mem16,segreg

mov stack_save,ss

1

MOV reg32,controlreg

mov eax,cr0

22

mov eax,cr2

12

mov eax,cr3

21, 46

mov eax,cr4

14

MOV controlreg,reg32

mov cr0,eax

4

MOV reg32,debugreg

mov edx,dr0

DR0-DR3, DR6,DR7=11

DR4,DR5=12

MOV debugreg,reg32

mov dr0,ecx

DR0-DR3,

DR4,DR5=12 DR6,DR7=11

 要求:

1)、两个操作数的数据类型要相同,要同为8位、16位或32位;如:MOV  BL, AX等是不正确的;
2)、两个操作数不能同时为段寄存器,如:MOV  ES, DS等;  (实现方式:mov ax, dx            mov es, ax

3)、代码段寄存器CS不能为目的操作数,但可作为源操作数,如:指令MOV  CS, AX等不正确,但指令MOV  AX, CS等是正确的;

4)、立即数不能直接传给段寄存器,如:MOV  DS, 100H等;   (实现方式:mov ax, 100h        mov ds, ax)
5)、立即数不能作为目的操作数,如:MOV  100H, AX等;
6)、指令指针IP,不能作为MOV指令的操作数;

7)、两个操作数不能同时为存储单元,如:MOV  VARA, VARB等,其中VARA和VARB是同数据类型的内存变量。

            (实现方式:mov ax varb     mov vara  ax)

1.2、传送-填充指令(80386  )

        MOVSX(符号填充)/MOVZX(零填充)   Reg/Mem,  Reg/Mem/Imm     ;80386+

        MOVSX的填充方式是:用源操作数的符号位来填充目的操作数的高位数据位。

        MOVZX的填充方式是:恒用0来填充目的操作数的高位数据位。

       

MOVSX reg,reg 

movsx bx,al

3

MOVSX reg,mem

movsx eax,bsign

3

MOVZX reg,reg

movzx bx,al

3

MOVZX reg,mem

movzx eax,bunsign

3

1.3、交换指令

           寄存器不能是段寄存器,两个操作数也不能同时为内存变量。

XCHG reg,reg

xchg cx,dx

3

XCHG reg,mem

xchg bx,pointer

3

XCHG mem,reg

xchg [bx],ax

3

XCHG accum,reg

xchg ax,cx

2

XCHG reg,accum

xchg cx,ax

2

1.4、取段地址和有效地址指令

       lea(load effective address)  取有效地址

       lds, les,    取段寄存器  根据d,e等判定哪个寄存器

       lfs, lgs, lss  (32bit)

         lea该指令通常用来对指针或变址寄存器bx, di, si等设置初值用。

        buffer db  100 dup(?)

        lea      bx,  buffer                ;把字节变量buffer在数据段内的偏移量送给bx。

       

      

LDS reg,mem

lds si,fpointer

4

LES reg,mem

les di,fpointer

4

LFS reg,mem

lfs edi,fpointer

4

LGS reg,mem

lgs bx,fpointer

4

LSS reg,mem

lss bp, fpointer

4, pm=8

LEA reg,mem

lea bx,npointer

1

1.5、进栈指令

       push,  一个字进栈,系统自动完成两步操作: sp<--sp-2,   (sp)<--操作数

                    一个双字进栈,系统自动完成  esp <-- esp-4, (esp) <----操作数

            pusha,功能是依次把ax, cx, dx, bx, bp, si, di等压栈。

PUSH reg

push dx

1

PUSH mem

push [di]

2

PUSH segreg

push es

1

PUSH immed

push 15000

1

PUSHA

pusha    ;+80286

5

PUSHAD

pushad

5

PUSHF 把16/32位标志寄存器进栈

pushf

4, pm=3

PUSHFD

pushfd

4, pm=3

1.6、出栈指令

      pop: 弹出一个字:    操作数<---(sp),   sp<--sp-2;

                 弹出一个双字: 操作数<---(esp), esp<---esp-4;

POP reg

pop cx

1

POP mem

pop param

3

POP segreg

pop es

3

POPA  

popa

5

POPAD

popad

5

POPF

popf

6, pm=4

POPFD

popfd

6, pm=4

1.7、转换指令

         有两个隐含操作数bx 和 al

       功能:把bx 的值作为内存字节数组首地址、下标为al的数组元素的值传送给al。   al<---bx[al].

         

XLAT [[segreg:]mem]

xlat

4

XLATB [[segreg:]mem]

xlatb es:table

4

 

2、标志位操作指令

2.1、标志位操作指令

指令的语法

举例

周期数

CLC   清进位指令 cf <--- 0

clc

2

CMC  进位取反指令 cf<--not cf

cmc

2

STC    置进位指令  cf<----1

stc

2

CLD  清方向位指令 if<--0

cld

2

STD  置方向位指令 if<--1

std

2

CLI   清中断允许指令 if <---0

cli

7

STI   置中断允许位指令if <--1

sti

7

2.2、标志位存取操作指令

SAHF   flags的低8位<---ah

Sahf

2

LAHF   ah<----flags的低8位

lahf

2

2.3、标志位堆栈操作指令

PUSHF

pushf

4, pm=3

PUSHFD

pushfd

4, pm=3

POPF

popf

6, pm=4

POPFD

popfd

6, pm=4

   

3、算术运算指令

3.1、加法指令

        add  加; 受影响的标志位:af  ,cf, of, pf, sf, zf

        adc  带进位加;受影响的标志位:af  ,cf, of, pf, sf, zf

        inc   加1指令;受影响的标志位:af  , of, pf, sf, zf   不影响cf

        xadd  交换加指令;受影响的标志位:af  ,cf, of, pf, sf, zf         ;80486+

指令的语法

举例

周期数

ADC reg,reg

adc dx,cx

1

ADC mem,reg

adc word ptr m16[2],dx

3

ADC reg,mem

adc dx,dword ptr m32[2]

2

ADD reg,reg

add ax,bx

1

ADD mem,reg

add total, cx

3

ADD reg,mem

add cx,incr

2

ADD reg,immed

add bx,6

1

ADD mem,immed

add pointers[bx][si],6

3

ADD accum,immed

add ax,10

1

INC reg

inc bx

1

INC mem

inc vpage

3

XADD reg,reg

xadd dl,al

3

XADD mem,reg

xadd string,bl

4

     

3.2、减法指令

      sub  减;         AF、CF、OF、PF、SF和ZF

      sbb 带错位减; AF、CF、OF、PF、SF和ZF,指令的功能是把源操作数和标志位CF的值从目的操作数中一起减去。

      dec  减一指令  AF、OF、PF、SF和ZF,不影响CF

       neg 求补指令  AF、CF、OF、PF、SF和ZF,指令的功能:操作数=0-操作数,即改变操作数的正负号。

SUB reg,reg

sub ax,bx

1

SUB mem,reg

sub array[di],bi

3

SUB reg,mem

sub al,[bx]

2

SUB reg,immed

sub bl,7

1

SUB mem,immed

sub total,4000

3

SUB accum,immed

sub ax,32000

1

SBB accum,immed

sbb ax,320

1

SBB reg,immed

sbb dx,45

1

SBB mem,immed

sbb word ptr m32[2],40

3

SBB reg,reg

sbb dx,cx

1

SBB mem,reg

sbb word ptr m32[2],dx

3

SBB reg,mem

sbb dx,word ptr m32[2]

2

DEC reg

dec ax

1

DEC mem

dec counter

3

NEG reg

neg ax

1

NEG mem

neg balance

3

3.3、乘法指令

乘法指令分为无符号乘法指令和有符号乘法指令,它们的唯一区别就在于:数据的最高位是作为“数值”参与运算,还是作为“符号位”参与运算

乘法指令的被乘数都是隐含操作数,乘数在指令中显式地写出来。CPU会根据乘数是8位、16位,还是32位操作数,来自动选用被乘数:ALAXEAX

指令的功能是把显式操作数和隐含操作数相乘,并把乘积存入相应的寄存器中。

无符号数乘法指令MUL(Unsigned Multiply Instruction)

指令的格式:MUL  Reg/Mem
             受影响的标志位:CF和OF(AF、PF、SF和ZF无定义)
             指令的功能是把显式操作数和隐含操作数(都作为无符号数)相乘,所得的乘积按表5.2的对应关系存放。

                                                      表5.2 乘法指令中乘数、被乘数和乘积的对应关系

乘数位数

隐含的被乘数

乘积的存放位置

举例

8位

AL

AX

MUL  BL

16位

AX

DX-AX

MUL  BX

32位

EAX

EDX-EAX

MUL  ECX

                                                           

              有符号数乘法指令IMUL(Signed Integer Multiply Instruction)

指令的格式: IMUL Reg/Mem
IMUL Reg, Imm ;80286+
IMUL Reg, Reg, Imm ;80286+
IMUL Reg, Reg/Mem ;80386+

受影响的标志位:CF和OF(AF、PF、SF和ZF无定义)

1)、指令格式1——该指令的功能是把显式操作数和隐含操作数相乘,所得的乘积按表5.2的对应关系存放。

2)、指令格式2——其寄存器必须是16位/32位通用寄存器,其计算方式为:

Reg ← Reg × Imm

3)、指令格式3——其寄存器只能是16位通用寄存器,其计算方式为:

Reg1 ← Reg2×Imm  或  Reg1 ← Mem×Imm

4)、指令格式4——其寄存器必须是16位/32位通用寄存器,其计算方式为:

Reg1 ← Reg1×Reg2  或  Reg1 ← Reg1×Mem

在指令格式2~4中,各操作数的位数要一致。如果乘积超过目标寄存器所能存储的范围,则系统将置溢出标志OF为1

MUL reg

mul bx

 

MUL memX

mul word ptr [bx]

8,16-bit=11

32-bit=10

IMUL reg

imul dx

11

IMUL mem

imul factor

11

IMUL reg,immed

imul cx,25

10

IMUL reg,reg,immed

imul dx,ax,18

10

IMUL reg,mem,immed

imul bx,[si],60

10

IMUL reg,reg

imul cx,ax

10

IMUL reg,mem

imul dx,[si]

10

3.4、除法指令

除法指令功能是用显式操作数去除隐含操作数,可得到商和余数。当除数为0,或商超出数据类型所能表示的范围时,系统会自动产生0号中断。

     

无符号数除法指令DIV(Unsigned Divide Instruction)

指令的格式:DIV  Reg/Mem
             指令的功能是用显式操作数去除隐含操作数(都作为无符号数),

所得商和余数按表5.3的对应关系存放。指令对标志位的影响无定义。

 

有符号数除法指令IDIV(Signed Integer Divide Instruction)

指令的格式:IDIV  Reg/Mem
            受影响的标志位:AF、CF、OF、PF、SF和ZF

指令的功能是用显式操作数去除隐含操作数(都作为有符号数),所得商和余数的对应关系见表5.3。

                                              表5.3 除法指令除数、被除数、商和余数的对应关系

除数位数

隐含的被除数

余数

举例

8位

AX

AL

AH

DIV  BH

16位

DX-AX

AX

DX

DIV  BX

32位

EDX-EAX

EAX

EDX

DIV  ECX

DIV reg

div cx

byte=17 word=25

DIV mem

div [bx]

dword=41

IDIV reg

idiv dl

8-bit=22;16-bit=30

IDIV mem

idiv itemp

32-bit=46

3.5、类型转换指令

CBW 字节转换指令

cbw

3

CWD  字转换位双字

cwd

2

CWDE字转换位扩展的双字 80386+

cwde

3

CDQ  字转换位4字节 80386+

cdq

2

4、逻辑运算指令

   CF(0)、OF(0)、PF、SF和ZF(AF无定义)

4.1、逻辑与操作指令

指令的语法

举例

周期数

AND reg,reg

and dx,bx

1

AND mem,reg

and bitmask,bx

3

AND reg,mem

and bx,masker

2

AND reg,immed

and dx,0F7h

1

AND mem,immed

and masker,100lb

3

AND accum,immed

and ax,0B6h

1

4.2、逻辑或操作指令

OR reg,reg

or ax,dx

1

OR mem,reg

or bits,dx

3

OR reg,mem

or dx,color[di]

2

OR reg,immed

or dx,110110b

1

OR mem,immed

or flag_rec,8

3

OR accum,immed

or ax,40h

1

4.3、逻辑非操作指令

NOT reg

not ax

1

NOT mem

not masker

3

4.4、逻辑异或操作指令

XOR reg,reg

xor cx,bx

1

XOR reg,mem

xor cx,flags

2

XOR mem,reg

xor [bp+10],cx

3

XOR reg,immed

xor bl,1

1

XOR mem,immed

xor switches[bx],101b

3

XOR accum,immed

xor ax,01010101b

1

5、移位操作指令

      受影响的标志位:CF、OF、PF、SF和ZF(AF无定义)。

5.1、算术左移指令

           算术左移SAL把目的操作数的低位向高位移,空出的低位补0;
  

指令的语法

举例

周期数

SAL reg,1

sal bx,1

1

SAL mem,1

sal word ptr m32[0],1

3

SAL reg,CL

sal ah,cl

4

SAL mem,CL

sal BYTE PTR [di],cl

4

SAL reg,immed

sal cx,6

1

SAL mem,immed

sal array[bx+di],14

3

5.2、算术右移指令

          算术右移SAR把目的操作数的高位向低位移,空出的高位用最高位(符号位)填补。

SAR reg,1

sar di,1

1

SAR mem,1

sar count,1

3

SAR reg,CL

sar bx,cl

4

SAR mem,CL

sar sign,cl

4

SAR reg,immed

sar bx,5

1

SAR mem,immed

sar sign_count,3

3

5.3、逻辑左移指令

      逻辑左移/右移指令只有它们的移位方向不同,移位后空出的位都补0

SHL reg,1

shl si,1

1

SHL mem,1

shl index,1

3

SHL reg,CL

shl di,cl

4

SHL mem,CL

shl index,cl

4

SHL reg,immed

shl di,2

1

SHL mem,immed

shl unsign,4

3

5.4、逻辑右移指令

SHR reg,1

shr dh,1

1

SHR mem,1

shr unsign[di],1

3

SHR reg,CL

shr dx,cl

4

SHR mem,CL

shr word ptr m32[2],cl

4

SHR reg,immed

shr bx,8

1

SHR mem,immed

shr mem16,11

3

5.5、双精度左移指令

SHLD reg16,reg16,immed8

shld ax,dx,10

4

SHLD reg32,reg32,immed8

     

SHLD mem16,reg16,immed8

shld bits,cx,5

4

SHLD mem32,reg32,immed8

     

SHLD reg16,reg16,CL

shld ax,dx,cl

4

SHLD reg32,reg32,CL

     

SHLD mem16,reg16,CL

shld masker,ax,cl

5

SHLD mem32,reg32,CL

     

5.6、双精度右移指令   80386+

SHRD reg16,reg16,immed8

shrd cx,si,3

4

SHRD reg32,reg32,immed8

SHRD mem16,reg16,immed8

shrd [di],dx,5

4

SHRD mem32,reg32,immed8

SHRD reg16,reg16,CL

shrd ax,dx,cl

4

SHRD reg32,reg32,CL

SHRD mem16,reg16,CL

shrd [bx],ax,cl

5

SHRD mem32,reg32,CL

5.7、循环左移指令  (cf 和 of)

            循环左移/右移指令只是移位方向不同,它们移出的位不仅要进入CF,而且还要填补空出的位

指令的语法

举例

周期数

ROL reg,1

rol ax,1

1

ROL mem,1

rol bits,1

3

ROL reg,CL

rol ax,cl

4

ROL mem,CL

rol color,cl

4

ROL reg,immed8

rol ax,13

1

ROL mem,immed8

rol byte ptr [bx],10

3

5.8、循环右移指令

ROR reg,1

ror ax,1

1

ROR mem,1

ror word ptr [bx],1

3

ROR reg,CL

ror dx,cl

4

ROR mem,CL

ror color,cl

5

ROR reg,immed8

ror bl,3

1

ROR mem,immed8

ror bits,6

3

5.9、带进位的循环左移指令

      

RCL reg,1

rcl dx,1

1

RCL mem,1

rcl WORD PTR [si],1

3

RCL reg,CL

rcl dx,cl

7-24

RCL mem,CL

rcl masker,cl

9-26

RCL reg,immed8

rcl bx,5

8-25

RCL mem,immed8

rcl word ptr [bp+8],3

10-27

5.10、带进位的循环右移指令

RCR reg,1

rcr bl,1

1

RCR mem,1

rcr word ptr m32[0],1

3

RCR reg,CL

rcr bl,cl

7-24

RCR mem,CL

rcl word ptr [bx=di],cl

9-26

RCR reg,immed8

rcr si,9

8-25

RCR mem,immed8

rcr masker,3

10-27

6、位操作指令

6.1、正向位扫描指令

指令的语法

举例

周期数

BSF reg16,reg16

bsf cx,bx

6-34

BSF reg32,reg32

bsf cx,bx

6-42

BSF reg16,mem16

bsf ecx,bitmask

6-35

BSF reg32,mem32

bsf ecx,bitmask

6-43

6.2、逆向位扫描指令

BSR reg16,reg16

bsr cx,dx

7-39

BSR reg32,reg32

bsr ecx, edx

7-71

BSR reg16,mem16

bsr ax,bitmask

7-40

BSR reg32,mem32

bsr eax,bitmask

7-72

6.3、位检测指令

BT reg16,immed8*(注)

bt ax,4

4

BT mem16,immed8

bt [bx],4

4

BT reg16,reg16

bt ax,bx

4

BT mem16,reg16

bt [bx],dx

9

(注) 操作数也可以是32位数。

6.4、正向位扫描指令

BTC reg16,immed8*

btc edi,4

7

BTC mem16,immed8*

btc color[di],4

8

BTC reg16,reg16*

btc eax,ebx

7

BTC mem16,reg16*

btc [bp+8],si

13

6.5、正向位扫描指令

BTR reg16,immed8*

btr bx,17

7

BTR mem16,immed8*

btr [bx],27

8

BTR reg16,reg16*

btr cx,di

7

BTR mem16,reg16*

btr rotate,cx

13

6.6、正向位扫描指令

BTS reg16,immed8*

bts ax,4

7

BTS mem16,immed8*

bts maskit,4

8

BTS reg16,reg16*

bts bx,ax

7

BTS mem16,reg16*

bts flags[bx],cx

13

6.7、正向位扫描指令

TEST reg,reg

test dx,bx

1

TEST mem,reg

test flags,dx

2

TEST reg,immed

test cx,30h

1

TEST mem,immed

test masker,1

2

TEST accum,immed

test ax,90h

1

7、比较运算指令

7.1、比较指令

指令的语法

举例

周期数

CMP reg,reg

cmp dl,cl

1

CMP mem,reg

cmp array[si],bl

2

CMP reg,mem

cmp bh,array[si]

2

CMP reg,immed

cmp bx,24

1

CMP mem,immed

cmp tester,4000

2

CMP accum,immed

cmp ax,1000

1

7.2、比较交换指令

CMPXCHG mem,reg

cmpxchg string,bl

6

CMPXCHG reg,reg

cmpxchg bx,cx

6

CMPXCHG8B reg,mem64

cmpxchg8b ax,[bx]

10

8、循环指令

  

循环结构是程序的三大结构之一。为了方便构成循环结构,汇编语言提供了多种循环指令,这些循环指令的循环次数都是保存在计数器CXECX中。除了CXECX可以决定循环是否结束外,有的循环指令还可由标志位ZF来决定是否结束循环。

在高级语言中,循环计数器可以递增,也可递减,但汇编语言中,CXECX只能递减,所以,循环计数器只能从大到小。在程序中,必须先把循环次数赋给循环计数器。

汇编语言的循环指令都是放在循环体的下面,在循环时,首先执行一次循环体,然后把循环计数器CXECX减1。当循环终止条件达到满足时,该循环指令下面的指令将是下一条被执行的指令,否则,程序将向上转到循环体的第一条指令。

在循环未终止,而向上转移时,规定:该转移只能是一个短转移,即偏移量不能超过128,也就是说循环体中所有指令码的字节数之和不能超过128

 

8.1、循环指令

LOOP label

loop wend

5, 6

LOOPE label  

loope again

7, 8

LOOPZ label

loopz again

7, 8

LOOPNE label

loopne for_next

7, 8

LOOPNZ label

loopnz for_next

7, 8

8.2、循环指令

JCXZ label

jcxz notfound

6,5

JECXZ label

jecxz notfound

6,5

      

9、转移指令

9.1、无条件转移指令

             jmp

         包括:JMP、子程序的调用返回指令、中断的调用返回指令等。

                              JMP  标号/Reg/Mem

JMP指令是从程序当前执行的地方无条件转移到另一个地方执行。这种转移可以是一个短(short)转移(偏移量在[-128, 127]范围内),近(near)转移(偏移量在[-32K, 32K]范围内)或远(far)转移(在不同的代码段之间转移)。

短和近转移是段内转移,JMP指令只把目标指令位置的偏移量赋值指令指针寄存器IP,从而实现转移功能。但远转移是段间转移,JMP指令不仅会改变指令指针寄存器IP的值,而且还会改变代码段寄存器CS的值。 

指令的语法

举例

周期数

JMP label

jmp NEAR PTR distant

1

jmp distant

3

JMP reg16

jmp ax

2

JMP mem16

jmp table[di]

2

JMP reg32

jmp eax

3

JMP mem32

jmp fpointer[si]

2

JMP mem48

jmp FWORD PTR [di]

4

9.2、条件转移指令

条件转移指令是一组极其重要的转移指令,它根据标志寄存器中的一个(或多个)标志位来决定是否需要转移,这就为实现多功能程序提供了必要的手段。微机的指令系统提供了丰富的条件转移指令来满足各种不同的转移需要,在编程序时,要对它们灵活运用。

条件转移指令又分三大类:基于无符号数的条件转移指令、基于有符号数的条件转移指令和基于特殊算术标志位的条件转移指令

无符号数的条件转移指令(Jumps Based on Unsigned (Logic) Data)

指令的助忆符

检测的转移条件 功能描述

JE/JZ

ZF=1 Jump Equal or Jump Zero

JNE/JNZ

ZF=0 Jump Not Equal or Jump Not Zero

JA/JNBE

CF=0 and ZF=0 Jump Above or Jump Not Below or Equal

JAE/JNB

CF=0 Jump Above or Equal or Jump Not Below

JB/JNAE

CF=1 Jump Below or Jump Not Above or Equal

JBE/JNA

CF=1 or AF=1 Jump Below or Equal or Jump Not Above

有符号数的条件转移指令(Jumps Based on Signed (Arithmetic) Data)

指令的助忆符

检测的转移条件 功能描述

JE/JZ

ZF=1 Jump Equal or Jump Zero

JNE/JNZ

ZF=0 Jump Not Equal or Jump Not Zero

JG/JNLE

ZF=0 and SF=OF Jump Greater or Jump Not Less or Equal

JGE/JNL

SF=OF Jump Greater or Equal or Jump Not Less

JL/JNGE

SF≠OF Jump Less or Jump Not Greater or Equal

JLE/JNG

ZF=1 or SF≠OF Jump Less or Equal or Jump Not Greater

特殊算术标志位的条件转移指令(Jumps Based on Special Arithmetic Tests)

指令的助忆符

检测的转移条件 功能描述

JC

CF=1 Jump Carry

JNC

CF=0 Jump Not Carry

JO

OF=1 Jump Overflow

JNO

OF=0 Jump Not Overflow

JP/JPE

PF=1 Jump Parity or Jump Parity Even

JNP/JPO

PF=0 Jump Not Parity or Jump Parity Odd

JS

SF=1 Jump Sign (negative)

JNS

SF=0 Jump No Sign (positive)

             

              

9.3、子程序调用指令

CALL label

call upcase

1

call distant

4

CALL reg

call ax

2

CALL mem32

call [bx]

2

CALL mem32

call dword ptr [bx]

5

9.4、子程序返回指令

RETN

retn

2

RETN immed16

retn 8

3

RETF

retf

4, 23

RETF immed16

retf 32

4, 23

9.5、中断指令

INT immed8

int 25h

16, pm=31, 48*(注)

INT 3

int 3

13, pm=27, 44*

INTO

Into

13, pm=27, 44*

注:第一时间是同等优先级的中断时间,第二时间为高优先级的中断时间。

9.6、中断返回指令

IRET

Iret

8*(注),10, pm=27

IRETD

Iretd

10, pm=27

IRETF

Iretf

IRETDF

Iretdf

注:实方式或虚拟8086方式。

10、条件设置字节指令  

           setnn   

            不影响任何标志位

条件设置字节指令(Set Byte Conditionally)是80386及其以后CPU所具有的一组指令。它们在测试条件方面与条件转移是一致的,但在功能方面,它们不是转移,而是根据测试条件的值来设置其字节操作数的内容为1或0。

SETcondition reg8

setc dh

1

SETcondition mem8

setle flag

2

          

11、字符串操作指令

          字符串操作指令的实质是对一片连续存储单元进行处理,这片存储单元是由隐含指针DS:SIES:DI来指定的。字符串操作指令可对内存单元按字节、字或双字进行处理,并能根据操作对象的字节数使变址寄存器SI(和DI)增减1、2或4。

           

                      (1)、当DF=0时,变址寄存器SI(和DI)增加1、2或4;
                      (2)、当DF=1时,变址寄存器SI(和DI)减少1、2或4。

11.1、取字符串数据指令       

             lods (load string instruction )

指令的语法

举例

周期数

LODS [segreg:]src

lods es:source

2

LODSB [[segreg:]src]

Lodsb

2

LODSW [[segreg:]src]

Lodsw

2

LODSD [[segreg:]src]

Lodsd

2

11.2、置字符串数据指令  df

         stos

STOS [ES:]dest

stor es:dstring

3

STOSB [[ES:]dest]

stosb

3

STOSW [[ES:]dest]

stosw

3

STOSD [[ES:]dest]

stosd

3

11.3、字符串传送指令      df

         movs

MOVS [es:]dest, [segreg:]src

movs dest,es:source

4

MOVSB [[es:]dest, [segreg:]src]

movsb

4

MOVSW [[es:]dest, [segreg:]src]

movsw

4

MOVSD [[es:]dest, [segreg:]src]

movsd

4

11.4、输入字符串指令

         ins

该指令是从某一指定的端口接受一个字符串,并存入一片存储单元之中。输入端口由DX指定,存储单元的首地址和读入数据的个数分别由ES:DICX来确定。在指令的执行过程中,还根据标志位DF对寄存器DI作相应增减。

该指令不影响任何标志位。

INS [ES:]dest, DX

ins es:instr,dx

9, pm=6,24*, vm=22

INSB

Insb

9, pm=6,24*, vm=22

INSW

Insw

9, pm=6,24*, vm=22

INSD

Insd

9, pm=6,24*, vm=22

11.5、输出字符串指令

            outs

该指令是把一个字符串输入到指定的输出端口中。输出端口由DX指定,其输出数据的首地址和个数分别由DS:SICX来确定。在指令的执行过程中,还根据标志位DF对寄存器SI作相应增减。

该指令的执行不影响任何标志位。

OUTS DX,[segreg:]src

outs dx,buffer

13, pm=10,27, VM=24

OUTSB [DX,[segreg:]src]

outsb

13, pm=10,27, VM=24

OUTSW [DX,[segreg:]src]

outsw

13, pm=10,27, VM=24

OUTSD [DX,[segreg:]src]

outsd

13, pm=10,27, VM=24

11.6、字符串比较指令  af, cf, of, pf, sf, zf

          cmps

该指令是把一个字符串输入到指定的输出端口中。

输出端口由DX指定,其输出数据的首地址和个数分别由DS:SICX来确定。

在指令的执行过程中,还根据标志位DF对寄存器SI作相应增减。该指令的执行不影响任何标志位。

 

CMPS [segreg:] src, [ES:]dest

cmps source,es:dest

5

CMPSB [[segreg:[src,] ES:] dest]

cmpsb

5

CMPSW [[segreg:[src,] ES:]dest]

cmpsw

5

CMPSD [[segreg:[src,] ES:] dest]

cmpsd

5

11.7、字符串扫描指令  af, cf, of, pf, sf, zf

          scas  (scan string instruction)

         该指令是用指针 es: di  所指向字节,字,或双字的值与相应的al、ax、eax的值相减,

         用所得到的差来设置有关标志位。

         与此同时,变址寄存器di还将根据标志位df的值来进行增减。

SCAS [ES]:dest

scas es:destin

4

SCASB

Scasb

4

SCASW

Scasw

4

SCASD

Scasd

4

11.8、重复前缀指令

          rep(repeat string instruction)

         但我们知道:每个字符串通常会有多个字符的,所以,就需要重复执行这些字符串操作指令。为了满足这种需求,指令系统提供了一组重复前缀指令。

重复字符串操作指令对标志位的影响是由被重复的字符串操作指令来决定。

重复前缀指令的执行步骤如下:

(1)、判断:CX=0;
            (2)、如果CX=0,则结束重复操作,执行程序中的下一条指令;
            (3)、否则,CX=CX-1(不影响有关标志位),并执行其后的字符串操作指令,在该指令执行完后,再转到步骤(1)。

             重复前缀指令是重复其后的字符串操作指令,重复的次数由CX来决定。其一般格式为:

                 REP LODS/LODSB/LODSW/LODSD
                 REP STOS/STOSB/STOSW/STOSD
                 REP MOVS/MOVSB/MOVSW/MOVSD
                 REP INS/ INSB/INSW/INSD
                 REP OUTS/OUTSB/OUTSW/OUTSD

注:当CPL≤IOPL时,执行时间是第一个时钟周期,否则是第二个时钟周期。

    

11.9、相等重复前缀指令    zf

             repe(repeat string conditionaly)

 条件重复前缀指令与前面的重复前缀指令功能相类似,

 所不同的是:其重复次数不仅由CX来决定,而且还会由标志位ZF来决定。

 根据ZF所起的作用又分为二种:相等重复前缀指令REPE/REPZ和不等重复前缀指令REPE/REPZ。

该重复前缀指令的执行步骤如下:

(1)、判断条件:CX≠0 且 ZF=1;
(2)、如果条件不成立,则结束重复操作,执行程序中的下一条指令;
(3)、否则,CX=CX-1(不影响有关标志位),并执行其后的字符串操作指令,在该指令执行完后,再转到步骤(1)。

REPE CMPS src,dest

repe cmps src,dest

7, 9+4n

REPE SCAS dest

repe scas dest

7, 9+4n

11.10、不相等重复前缀指令       zf

           repne

该重复前缀指令的执行步骤如下:

(1)、判断条件:CX≠0 且 ZF=0;
(2)、如果条件不成立,则结束重复操作,执行程序中的下一条指令;
(3)、否则,CX=CX-1(不影响有关标志位),并执行其后的字符串操作指令,在该指令执行完后,再转到步骤(1)。

REPNE CMPS src,dest

repne cmps src,dest

7, 8+4n

REPNE SCAS dest

repne scas dest

7, 9+4n

12、ASCII-BCD码运算调整指令   很少运用到实际程序中

指令的语法

举例

周期数

AAA   加调整  af  cf

aaa

3

AAD  除调整  pf sf  zf

aad

10

AAM  乘调整  pf  sf  zf

aam

18

AAS  减调整   af  cf

aas

3

DAA  十进制数加调整

daa

3

DAS  十进制数减调整

das

3

    用法:aaa

        

    aas

      

   aam  和  aad

          

           daa 和 das

          

13、处理器指令   使用率不高  

HLT

Hlt

12

NOP

nop

1

WAIT

wait

1

LOCK

lock

1

14、协处理器指令   使用率不高

指令的语法

举例

周期数

FBLD membcd fbld packbck 48-58
FBSTP membcd fbstp bcds[bx] 148-154
FLD reg fld st(3) 1
FLD mem32real fld longreal 1
FLD mem64real   1
FLD mem80real   3
FST reg fst st 1
FST memreal fst longs[bx] 2
FSTP reg fstp st(3) 1
FSTP mem32real fstp longreal 2
FSTP mem64real   2
FSTP mem80real   3
FXCH [reg] fxchg st(3) 1
FILD memint fild quads[si] 3, 1
FIST memint fist doubles[8] 6
FISTP memint fistp longint 6

猜你喜欢

转载自blog.csdn.net/WeiLuckyStrike/article/details/89352282