汇编总复习:来不及版

第一章汇编语言基础知识

一、BCD码

1)二进制编码的十进制数

一个十进制数位094位二进制编码来表示

常用8421 BCD码:低104位二进制编码表示

压缩BCD码:一个字节表达两位BCD码 

非压缩BCD码:一个字节表达一位BCD码(低4位表达数值,高4位常设置为0)

压缩BCD和非压缩BCD举例:
eg:

压缩BCD:0011 0001

非压缩BCD:0000 0011 0000 0001

2)ASCII码

(1)标准ASCII码用7位二进制编码,有128

(2)不可显示的控制字符

      前32个和最后一个编码

      回车CR0DH   换行LF0AH   响铃BEL07H

(3)可显示和打印的字符:20H开始的95个编码

数码0930H39H

大写字母AZ41H5AH

小写字母az61H7AH

空格:20H

3)基本数据类型

二、8086微处理器

1)8086寄存器

(1)数据寄存器

用来保存操作数或运算结果等

AX:累加器。用于算术、逻辑运算以及与外设传送信息等。
BX:基址寄存器,常于存放存储器地址
CX:计数器, 作为循环或串操作等指令中的隐含计数器
DX:数据寄存器,用来存放双字数据的高16位,或存放外设端口地址

(2)指针寄存器

用来存放某个存储单元的偏移地址

SP:SP用于存放当前堆栈段中地址栈顶的偏移

BP:用于存放堆栈段中某一存储单元的偏移地址

SI/DI:在字符串操作中,SI和DI都具有自动增量或减量的功能。

(3)控制寄存器

IP:保存下一次将要取出指令的偏移地址,IP的内容由微处理器硬件自动设置,有一些指令可改变IP的值,如转移指令、子程序调用指令等。
FLAGS:包含9个标志位,保存一条指令执行后,CPU所处状态信息及运算结果的特征。

   状态标志

    进位标志CF:记录算术运算或逻辑运算的最高位是否有进位或借位,用于无符号数的溢出检  测。运算
   零标志ZF:记录结果是否为零,用于判断相等或非零条件。
   符号标志SF:记录运算结果的符号位,用于判断正负条件。
   溢出标志OF:记录有符号数运算是否发生溢出,即结果超出了有符号数的表示范围。

8 位表示的整数范围是:- 128 ~+ 127
16 位表示的整数范围是:- 32768 ~+ 32767
如果运算结果超出这个范围,就产生了溢出


   奇偶标志PF:记录运算结果的最低字节中1的个数是否为偶数,用于校验或加密等操作。
   辅助进位标志AF:记录算术运算或逻辑运算的第四位是否有进位或借位,用于BCD码的运算。

常用的控制标志:

   方向标志DF:控制字符串操作指令中源地址和目的地址的增减方向,即从高地址向低地址还是 从低地址向高地址移动。
  终端允许标志IF:控制是否允许外部中断请求,即开启或关闭中断响应功能。
  追踪标志TF:控制是否进入单步执行模式,即每执行一条指令后产生一个调试异常,用于调试程序。

(4)段寄存器

CS,DS,SS,ES段寄存器用来确定该段在内存中的起始地址。

2)8086存储器组织

(1)存储单元的地址

       定义将存储单元编号,这个编号就是存储器地址。

       表示用十六进制数来表达地址。

每一个字节单元都有一个与之对应的单元地址 。

对于多字节单元(字,双字,4字等),其地址同样是采用最低位字节地址来表示的。

(2)存储器的地址分段

每一段的大小为64KB,则可访问的存储空间为2^4 * 2^16=2^20=1MB

段的起始地址有限制,段不能起始于任意地址,而必须从任一小段(Paragraph)的首地址开始。

除非专门指定,如用户自行设定之外,在一般情况下,各段在存储器中的分配是由操作系统负责的。每个段可以独立地占用64KB存储区。各段也允许部分重叠或完全重叠

(3)存储单元的内容

低位字节存入低地址单元,高位字节存入高地址单元。

eg:

0004H字节单元的内容: (0004H=34H

0004H字单元的内容:   (0004H=1234H

(4)隐含段和偏移寄存器

段寄存器和偏移寄存器组合有一定规则。

3)8086寻址方式

更多详情看计组

主要讲有效地址和物理地址

(1)数据寻址方式

物理地址=DS*10+EA

(1)立即数寻址方式
定义:操作数直接放在指令中
mov av,44h
注意:立即数只能作为源操作数
(2)寄存器寻址方式
定义:操作数存放在寄存器(8位,16位,32位,段寄存器)中
mov bl,al
(3)直接寻址方式:
定义:操作数字存储器中:
mov bl,[2000H]; mov al,number
注意:除了movs指令,系统不支持直接从内存到内存的传递

若指令为  MOV  AXES[VALUE],则对应该SRC的物理地址为 ES×10H+EA
(4)寄存器间接寻址方式:
定义:操作数的地址在基址或变址寄存器中
mov cl,[bx]

      PA=DS×10HBXSIDI

             PA=SS×10HBP

         PA=ES×10HBXSIDI
(5)基址变址寻址方式:
定义:用一个基址寄存器和一个变址寄存器间接寻址内存
有效地址ea = bx/bp + si/di
mov ax,[bx+si]; mov bx,[bp+di]
如果基址寄存器用bx,则默认段为数据段ds。如果用bp,则默认段为数据段ss

物理地址:PA=段基址×10H + EA
(6)寄存器相对寻址方式:
定义:用基址或变址寄存器内容位移量来寻址内存
有效地址ea = bx/bp/si/di + 位移量
其中bx,si,di默认数据段dsbp寄存器默认堆栈段ss
mov bl,[bx+10]; mov array[si],cl

(修改*10不是*16)
(7)相对基址变址寻址方式
定义:用一个基址加一个变址寄存器的内容再加上偏移量寻址内存
有效地址ea = bx/bp + si/di + 位移量
mov bl,[bp+di+100]

(2)程序存储器寻址方式


用途:确定转移指令和子程序调用指令的转向地址

段内直接寻址(Intrasegment direct addressing

目标转移地址中的有效地址是当前IP寄存器内容和指令中指定的8位或16位位移量之和。计算公式为:

              IP目标=IP当前+DISP       

       当前IP总是指向下一条指令的首地址

        1.当位移量为8位时,称为短转移,指令格式为:

             JMP  SHORT  DISP

            转移范围相对于当前IP:        -128 ~ +127

        2.当位移量为16位时,称为近转移,指令格式为:

             JMP  NEAR  PTR DISP

            转移范围相对于当前IP-32768 ~ +32767

段内直接寻址---短转移(扩展)

】: 已知在1000H单元中,有一条二字节指令:

      JMP SHORT NEXT ,设:1)位移量为20H;(2)位移量为80H。试计算有效转移地址。

分析:当前IP的值=1002H

   (1)  IP目标=1002H+0020H=1022H

   (2)  IP目标=1002H+0FF80H=0F82H

注意由于IP内容为16位的,若是短转移,其位移量为8,需对其进行符号扩展,变为16位。

扩展方法:高8位内容用符号位的值进行填充。

段内间接寻址(Intrasegment indirect addressing

     :已知 TABLE = 20A2H  (BX) = 1256H,    (SI) = 528EH(DS) = 2000H,  (232F8H) = 3280H (264E4H) = 2450H。试分析下列指令执行完后,对应的有效转移地址。

    (1JMP BX

    (2JMP TABLE[BX]  ( JMP WORD PTR TABLE[BX] )

    (3JMP  [BX][SI]   (   JMP  WORD PTR  [BX][SI]   )。

:(1IP目标=1256H;       

第二章8086指令系统

一、数据传送指令

功能:把数据、地址或立即数传送到寄存器或存储单元中

1.MOV指令

格式: MOV DST,SRC
功能:将源操作数SRC的内容传送到目标操作数
立即数→通用寄存器/存储单元: mov al,→ 44 , mov [di],78h
存储器 → 通用寄存器/段寄存器(除CS): mov ax,[bx] , mov ds,[2000h]
寄存器 → 寄存器/存储器/段寄存器(除CS): mov si,di , mov [2000H],cx , mov ds,bx
段寄存器 → 通用寄存器/存储器: mov bx,es , mov [bx],es

2.xchg 指令

格式: XCHG OPR1,OPR2
功能:完成OPR1操作数与OPR2操作数内容的交换
寄存器之间交换: xchg ax,dx
寄存器和存储单元之间交换: xchg al,[si]

3.xlat换码指令

格式: XLAT或XLAT OPR
功能:将AL与BX内容之和为偏移地址的存储单元内容送入AL

不允许直接通过 MOV 指令来修改代码段寄存器 CS

要改变 CS 的值,可以使用远跳转(far jump):

  1. 使用远跳转(far jump)改变 CS
    JMP FAR PTR new_segment:new_offset

  2. 例如:
    JMP 1234h:0000h ; 将 CS 改变为 1234h,并将 IP 改变为 0000h

  • MOV 指令用于数据传输。
  • WORD PTR 指定了传输的数据大小为一个字(16位)。
  • [BX] 表示要传输到的内存地址,BX 寄存器中存储了内存地址。
  • 0100H 是要传输的数据,是一个16位的立即数

  • 段寄存器不能直接用立即数传递

判断下列指令是否正确,不正确说明错误的原因

1、 MOV DS,0

2、 MOV AX,[SI][DI]

3、 MOV [BX],10H

4、 MOV AH,BX

5、 MOV [BX][SI]

6、 MOV CS,AX

7、 MOV [BX][SI],2

8、   MOV MYDATA[BX][SI],ES:AX

1 错误,立即数不能直接传送给数据段寄存器

2、错误,SIDI不能同时使用

3、错误,无法知道操作数的类型,即不知道是字节还是字

4、错误,源操作数和目的操作数的类型不一样

5、错误,源操作数和目的操作数不能同时为内存操作数

6、错误,CS不能作目的操作数

7、错误,无法知道操作数的类型,即不知道是字节还是字

8、错误,源操作数寻址错误

二、堆栈操作指令

特点: 堆栈是一个先进后出的数据结构,SS记录其段地址,栈顶用SP指定。栈顶地址较小(低端),栈底不变。(即栈开头向上)

PUSH 指令只能用于16位(如 AXBX)和32位(如 EAXEBX)的寄存器,而不能用于8位寄存器(如 ALAHBL 等)
1. push指令
格式: PUSH SRC
功能:将源操作数内容压栈,同时自动修改栈顶指针
2. pop指令
格式: POP DST
功能:从堆栈弹出数据
注意:出栈的顺序与入栈的顺序恰好相反

数据存储在CX里,push一次sp-2,pop一次sp+2

三、标志传送指令

1)标志位传送指令

标志寄存器传送指令用来传送标志寄存器FLAGS的内容

24条指令:

8位传送:LAHFSAHF

lahf指令:
格式: LAHF
功能:将标志寄存器的 SF/ZF/AF/PF/CF 位送AH寄存器的7/6/4/2/0位
sahf指令
格式: SAHF
功能:根据AH 的第7/6/4/2/0位设置标志寄存器的S/Z/A/P/C 位

16位传送:PUSHFPOPF

pushf指令
格式: PUSHF

SP←SP2
SS:[SP]←FLAGS
功能:PUSHF指令将标志寄存器的内容压入堆栈,同时栈顶指针SP2
popf指令
格式: POPF

FLAGS←SS:[SP]
SP←SP2
功能:POPF指令将栈顶字单元内容送标志寄存器,同时栈顶指针SP2

2)标志位操作指令

特点:只影响本指令指定的标志位,不影响其他标志位
clc      cf变0  (clear carry flag)
cmc    cf求反   (complement carry flag)
stc      cf变1   (set carry flag)
cld      df变0   (clear direction flag)
std      df变1   (set direction flag)
cli       if变0   (clear interrupt enable flag)
sti       if变1   (set interrupt enable flag)

四、地址传送指令

功能:用来传送操作数的地址

1)有效地址传送指令  LEA

LEA

将存储器操作数的有效地址传送至指定的16位寄存器中

格式: LEA REG,SRC(是一个存储单元)
功能:源操作数的有效地址(偏移地址)送指定寄存器
lea ax,numb

2)指针传送指令  LDSLES

LDS指令
格式: LDS REG,SRC
功能:将SRC存储单元存放的4个字节送指定的寄存器REG和
DS,其中(SRC)→ REG,(SRC+2)→ DS
lds di,list


LES指令
格式: LES REG,SRC
功能:将存储在SRC中的地址送REG寄存器和相应的段寄存器

在 x86 汇编中,PUSH 指令只能用于16位(如 AXBX)和32位(如 EAXEBX)的寄存器,而不能用于8位寄存器(如 ALAHBL 等)。

PUSH CS 是合法的,因为它将代码段寄存器 CS 的当前值压入栈中。
POP CS 是非法的,因为直接修改代码段寄存器 CS 是不安全的。

PA=0805H*10H+40H=08050H+40H=08090H,因为是栈底字单元,所以08090H-2=0808EH

PA=338AH*10H+(450-2-2)H=338A0H+44CH=33CECH

五、算术运算类指令

1.ADD、ADC、INC加法指令

ADD指令
格式: ADD DST,SRC
功能:将源操作数和目标操作数相加,结果送入目标操作数
ADD AL,BL , ADD CL,44


ADC指令

格式: ADC DST,SRC
功能:将源操作数、目标操作数和CF的值相加送目标操作数

双字加法

mov ax,4652h ;  ax = 4652h
add ax,0f0f0h ;  ax = 3742h,cf = 1
mov dx,0234h ;  dx = 0234h

adc dx,0f0f0h ;  dx = f325h,cf = 0(这里加了一个进位)
故dx.ax = 0234 4652h + f0f0 f0f0h = f325 3742h

 


INC指令(不影响CF标志位
格式: INC OPR
功能:将除段寄存器以外任何存储器或存储单元内容加1
inc bl , inc word ptr [bx]

2.SUB/SBB/DEC减法指令

SUB指令
格式: SUB DST,SRC
功能:从目标操作数中减去源操作数,结果存入目标操作数
SUB CX,BP


SBB指令
格式: SBB DST,SRC
功能:从目标操作数中减去源操作数和CF,结果存入目标操作数

双字减法

mov ax,4652h  ax=4652h

sub ax,0f0f0h  ax=5562hCF=1

mov dx,0234h  dx=0234h

sbb dx,0f0f0h  dx=1143hCF=1

DX.AX0234 4652HF0F0 F0F0H1143 5562H


DEC指令(不影响CF标志位)
格式: DEC OPR
功能:将目标操作数减1

3.NEG指令求补指令

格式: NEG OPR
功能:使操作数按位求反再加1,结果送入目标操作数(实际上是用0减去操作数,所以标志位是根据减法来设置的)

求补算法

mov ax,0ff64h
neg alax=ff9chOF=0SF=1ZF=0PF=1CF=1
sub al,9dhax=ffffhOF=0SF=1ZF=0PF=1CF=1
neg axax=0001hOF=0SF=0ZF=0PF=0CF=1
dec alax=0000hOF=0SF=0ZF=1PF=1CF=1
neg axax=0000hOF=0SF=0ZF=1PF=1CF=0

4.CMP比较指令

格式: CMP OPR1,OPR2
功能:用目标操作数减去源操作数根据结果设置标志位(不改变目标操作数,常用来判断两个的大小)

: 设XYZ均为双精度数。其存放地址为:XX+2YY+2ZZ+2。存放时,高位字在高位地址,低位字存放在低地址中。

     试编程完成       WX+Y+24-Z   ,结果存放在WW+2单元。

     16位下的操作

     MOV   AXX       ;用DXAX来表示双精度数
     MOV   DXX+2     ;低位用AX,高位用DX
    ADD    AXY       ;先低位运算
   ADC    DXY+2    ;完成X+Y
   ADD    AX24      ;低位运算
   ADC    DX0       ;高位运算,该语句不能少
  
SUB     AXZ      ;先低位减法
  
SBB      DXZ+2   ;完成运算
  
MOV    WAX      ;存储结果
  
MOV    W+2DX

5.乘法指令

MUL指令
格式: MUL SRC
功能:将累加器(AX或AL)与源操作数作为无符号数相乘
mul cl ; AL乘CL,无符号的积存在AX中
mul cx ; AX乘CX,无符号的积存在DX-AX中


IMUL
格式: IMUL SRC
功能:将累加器(AX或AL)与源操作数作为有符号数相乘
imul dh ; AL乘DH,有符号的积存在AX中
imul word ptr [si];AX内容与SI寻址的存储单元中字内容相乘,结果送DX:AX

例子:
无符号:
mov al,0b4h
mov bl,11h
mul bl ;OF=CF=1,AX高8位不为0
有符号:
mov al,0b4h
mov bl,11h
imul bl ;OF=CF=1,AX高8位含有效数字,不是低8位的符号扩展


乘法指令对标志的影响:
MUL指令-若乘积的高一半(AH或DX)为0则OF=CF=0;否则OF=CF=1
IMUL指令-若乘积的高一半是低一半的符号扩展则OF=CF=0;否则均为1,对标志位AF、PF、ZF、SF无定义

6.除法指令

div指令
格式: DIV SRC
功能:将两个无符号数相除
注意:
SRC为8位,目标操作数→AX(AX / SRC),商→AL中,余数→AH;
SRC为16位,目标操作数高位字→DX,低位字→AX(AX-DX / SRC),商→AX,余数→DX;


idiv指令
格式: IDIV SRC
功能:将两个有符号数相除

eg:
无符号
mov ax,0400h
mov bl,0b4h   ;商al=05h=5 余数ah=7ch=124
div bl
有符号
mov ax,0400h
mov bl,0b4h ;商al=f3h=-13 余数ah=24h=36
idiv bl

除法对标志的影响没有定义,却
可能产生溢出,会产生编号为0的内部中断

7.符号扩展指令

目的:为了使两个不同长度的数据类型做运算,例如一个16位+一个8位的数,需要将8位的数扩展到16位(用到cbw指令)
概念:扩展位字符由最高位决定,后一个操作数的各位是全0(正数)或全1(负数)(二进制)

CBW指令
格式: CBW
功能:将(AL)的符号位扩充到AH中

;如AL的最高有效位是0,则AH00

AL的最高有效位为1,则AHFFHAL不变

CWD指令
格式: CWD
功能:将(AX)的符号位扩充到DX中

;如AX的最高有效位是0,则DX0000H

AX的最高有效位为1,则DXFFFFHAX不变

eg:
mov al,80h  al=80h
cbw  ax=ff80h
add al,255  al=7fh
cbw  ax=007fh

综合运用:

综合运算举例。计算:     V-X*Y+Z-540))/X

       其中XYZV均为16位带符号数,已分别装入XYZV单元中,要求计算结果把商存入AX,余数存入DX

第一步,完成乘法运算X*Y: 
          MOV   AXX
          IMUL   Y

第二步,保存计算结果:低位保存到BX,高位保存到CX
         MOV    BXAX
         MOV    CXDX
注意:乘法运算完后,结果为32位数。

第三步:完成求和运算,X*Y+Z
        MOV    AXZ
        CWD
        ADD    BXAX
        ADC    CXDX

第四步:完成X*Y+Z-540
       SUB    BX540
       SBB    CX0

第五步:完成 V-X*Y+Z-540
        MOV   AXV
       CWD
       SUB    AXBX
       SBB    DX,CX

第六步:完成除法运算
       IDIV    X

结果:商送AX,余数送DX

注意:符号扩展不改变数据大小,不影响标志位

8.十进制调整指令

这组指令对二进制数运算的结果进行十进制调整


BCD码:
压缩BCD码:
四位二进制数表示一位十进制数(37->37)
非压缩BCD码:八位二进制数表示一位十进制数(37->0307),一般是低4位表示一个十进制数(0~9),高四位任意,但一般默认为0。


十进制数的运算步骤
1. 对BCD码进行二进制运算
2. 用十进制调整指令进行调整

(1)压缩BCD码调整指令(使用前先执行加减法操作,对OF无定义):


1.DAA
格式: DAA
指令功能 :将AL中的加和调整为压缩BCD码


2.DAS
格式: DAS
指令功能 :将AL中的减差调整为压缩BCD码

eg:

例:试完成压缩BCD码表示的1718,结果放DL

     MOV AL,17H

     ADD AL,18H

     DAA

     MOV DL,AL


压缩BCD减法例子

mov ax,1234h
mov bx,4612h
sub al,bl
das  34-1222CF0
xchg al,ah
sbb al,bh
das  12-4666CF=1
xchg al,ah  1 123446126622

(2)非压缩BCD码调整指令(也针对ASCALL码)

AAA指令
格式: AAA
指令功能:将AL中的加和调整为非压缩BCD码
使AL的高四位清零(即16进制下的第一位)
CF=AF=调整过程中产生进位,有进位要加1到ah中

AAAeg:

mov ax,0608h   ; 表示非压缩BCD码68
mov bl,09h   ; 表示非压缩BCD码9
add al,bl   ; al = 08h + 09h = 11h
aaa   ;十进制调整,进位一个给ah,将al=07h
;所以现在ax = 0707h,符合要求


AAS指令
格式: AAS
指令功能:将AL中的减差调整为非压缩BCD码
使AL的高四位清零(即16进制下的第一位)
CF=AF=调整过程中产生借位,有进位要从ah中减1

AAA AAS 指令在调整中产生了进位或借位,则 AH 要加上进位或减去借位,同时 CF=AF=1 ,否则 CF=AF=0 ;它们对其他标志无定义

AAM指令
格式: AAM ,跟在以AX为目的操作数的MUL指令后
指令功能:将AX中的乘积调整为非压缩BCD码
两个非压缩BCD码的高四位必须是
设置SF,ZF,PF位0

AAMeg:

mov ax,0608h ; 表示非压缩BCD码68
mov bl,09h ; 表示非压缩BCD码9
mul bl ; al = 08h * 09h = 0048h
aam ;所以现在ax = 0702h -> 8*9=72


AAD指令
格式: AAD ,在以AX为目的操作数的DIV指令前
指令功能:将AX中的非压缩BCD码扩展为二进制数
注意:非压缩BCD码除法调整是先调整后运算
;例:完成非压缩BCD码36除以6的运算。

AADeg:


MOV AX,0306H ;表示非压缩BCD码36
MOV BL,06H ;表示非压缩BCD码6
AAD ;将ax=36=0024h
DIV BL ;除法运算 商al=06h,余数ah=00h
;
mov ax,0608h ;表示非压缩bcd码68
mov bl,09h ;表示非压缩bcd码9
aad ;二进制扩展:ax=68=0044h
div bl;商al=07h,余数ah=05h

AAM AAD 指令 根据结果设置 SF ZF PF ,但对 OF CF AF 无定义

六、位操作类指令

1)逻辑运算指令

NOT指令
格式: NOT OPR
功能:将给定的操作数按位求反,且不影响标志位


OR指令
格式: OR DST,SRC
功能:将源与目标操作数按位“或”运算结果送目标操作数

OR指令设置CF = OF = 0,根据结果设置SFZFPF状态,而对AF未定义


例:将一位十进制数转化成相应的ASCII码
MOV AL,09H   ;9转化成ascii码
OR/ADD AL,30H

 

AND指令
格式: AND DST,SRC
功能:将源与目标操作数按位“与”运算,结果送目标操作数
AND指令设置CF = OF = 0,根据结果设置SFZFPF状态,而对AF未定义


XOR指令
格式: XOR DST,SRC
功能:将源与目标操作数按位“异或”运算,结果送目标操作数
将CX置0: XOR CX,CX
XOR指令设置CF = OF = 0,根据结果设置SFZFPF状态,而对AF未定义


TEST指令
格式: TEST OPR1,OPR2
功能:将两个操作数按位进行逻辑“与”运算不存结果只根据特征设置状态位
例:测试AL第二位是否为0,为0则转到EXIT执行。
TEST AL,0000 0100B
JZ EXIT

2)移位指令

逻辑左移右移都是补0。

算数左移补0,右移最高位不变。

3)控制转移类指令

(1)无条件转移指令JMP

功能:无条件地使程序转移到指定的目标地址
段内转移(改变IP的值,CS的值不变)


1. 直接方式(转移的目标地址直接出现在指令中)
格式: JMP 目标标号
功能: IP ← IP + disp


2. 间接方式(转移的目标地址在寄存器或存储单元中)
格式: JMP 字地址指针
功能: IP ← EA


段间转移(改变IP和CS的值)
1. 直接方式
格式: JMP 目标标号
功能: IP ← OFFSET 目标标号,CS← SEG 目标标号


2. 间接方式
格式: JMP 双地址指针
功能: IP ← [EA],CS← [EA+2]

(2)条件转移指令

功能:以某些标志位或标志位的逻辑运算为依据,满足条件,程序转移至指定目标;不满足条件,程序顺序执行。
注意:条件转移的目标地址 在当前IP地址的+127或-128字节的范围之内


1. 单个标志位的指令

(1)CF标志

         JB/JNAE/JC :CF=1时转移(进位/低于/不高于等于转移)
         JNB/JNC/JAE :CF=0时转移(不进位/不低于/高于等于转移

(2)ZF标志

         JE/JZ :ZF=1时转移(相等/等于0时跳转)
         JNE/JNZ :ZF=0时转移(不相等/不等于0时跳转)
(3)SF标志
         JS :SF=1时跳转(符号为负跳转)
         JNS :SF=0时跳转(符号为正跳转)
(4)PF标志
         JP/JPE :PF=1是跳转('1'的个数为偶数转移)(jmp if parity/jmp parity even)
         JNP/JPO :PF=0是跳转('1'的个数为奇数转移)
(5)OF标志
         JO :OF=1时跳转(溢出转移)
         JNO :OF=0时跳转(不溢出转移)

代码例子:

(1)计算|XY|(绝对值)

XY为存放于X单元和Y单元的16位操作数

;结果存入result

  mov ax,X

  sub ax,Y

  jns nonneg

  neg ax  neg是求补指令

nonneg:  mov result,ax

(2)计算XY

XY为存放于X单元和Y单元的16位操作数

;若溢出,则转移到overflow处理

  mov ax,X

  sub ax,Y

  jo overflow

  ...  ;无溢出,结果正确

overflow:  ...  ;有溢出处理

(3)设字符的ASCII码在AL寄存器中,将字符加上奇校验位。在字符ASCII码中为“1”的个数已为奇数时,则令其最高位为“0”;否则令最高位为“1”。

  and al,7fh

  ;最高位置0,同时判断1的个数

  jnp next

  ;个数已为奇数,则转向next

  or al,80h  ;否则,最高位置1

next:  ...

(4)记录BX1的个数

做法一:

  xor al,al  AL0CF0

again:  test bx,0ffffh ;等价于 cmp bx,0

  je next

  shl bx,1

  jnc again

  inc al

  jmp again

next:  ...  AL保存1的个数

做法二:

xor al,al  AL0CF0

again:  cmp bx,0

  jz next

  shl bx,1  ;也可使用 shr bx,1

  adc al,0

  jmp again

next:  ...  AL保存1的个数


2. 组合条件的条件转移指令

(1)无符号数
JA/JNBE :CF=0 且 ZF=0(高于/不低于等于转移)
JNA/JBE :CF=1 或 ZF=1(不高于/低于等于转移)


(2)有符号数
JG/JNLE :OF等于PF 且 ZF=1(大于/不小于等于转移)
JNG/JLE :OF不等于PF 或 ZF=0(不大于/小于等于转移)
JGE/JNL :OF等于PF(大于等于/不小于转移)
JNGE/JL :OF不等于PF(不大于等于/小于转移)
助记:JL(小于)为OF不等于PF,大于等于就是它的相反。然后小于等于就是小于或者等于,大于就是大于等于且不等于。


3. CX=0时转移:
格式: JCXZ
说明:(1)条件转移指令不影响标志位(2)条件转移指令前安排算术运算、比较、测试等影响相应标志位的指令。

代码例子

(1)比较无符号数

cmp ax,bx  ;比较axbx

  jnb next  ;若axbx,转移

  xchg ax,bx  ;若axbx,交换

next:  mov result,ax

(2)比较有符号数

cmp ax,bx  ;比较axbx

  jnl next  ;若axbx,转移

  xchg ax,bx  ;若axbx,交换

next:  mov result,ax

习题:

  SUB AL, AL:这条指令将 AL 减去自身,结果为 0。AL 被清零,并且 CF 被清零。此指令也正确实现了目标。
MOV AL, 00H:这条指令将 AL 设置为 0,但它不会影响 CF 标志。因此,这条指令不能保证 CF 被清零。

ADD BUF1, BUF2 尝试将两个内存位置相加,这是非法的操作。因此,这条指令会出错。

因为AX的最高位=1,所以符号扩展到DX后都为1,但是是正数所以是0FFFFH。
A-F在最高位,前面都要+0.

  • XOR BX, BX

    • 这条指令将 BX 与自身进行按位异或运算,结果总是 0,因此会将 BX 清零。
    • 这条指令也会清除进位标志(CF)和溢出标志(OF)。
  • OR BX, BX

    • 这条指令将 BX 与自身进行按位或运算,BX 的值保持不变。如果 BX 原来是 0,那么 BX 仍然是 0。
    • 但是,这条指令不会修改进位标志(CF)和溢出标志(OF)。
    • 这条指令不符合要求。
  • AND BX, BX

    • 这条指令将 BX 与自身进行按位与运算,BX 的值保持不变。如果 BX 原来是 0,那么 BX 仍然是 0。
    • 但是,这条指令不会修改进位标志(CF)和溢出标志(OF)。
    • 这条指令不符合要求。
  • CMP BX, BX

    • 这条指令比较 BX 与自身的值,结果总是相等,因此不会改变 BX 的值。
    • 虽然这条指令会影响标志位,但它不会将 BX 置零
    • 这条指令不符合要求

AL循环左移一位,28H=0010 1000,0101 0000,且无进位。

第三章汇编语言程序格式

二.语句格式

(1)伪指令语句:

含义:指定参与操作的数据。

个数:一般指令,1个或2个,也可以没有; 

      伪指令和宏指令,可以有多个。

书写规则:操作数多于1个时,操作数之间用逗号分开

名字定义满足的规则

1)数字不能作为第一个字符

2)单独的问号(?)不能作为名字

3)最大有效长度为31

4)保留字不能作为名字

三.符号定义语句伪指令

一)等值语句EQU

语句格式:符号名   EQU   表达式

1.常数或数值表达式

eg:
COUNT  EQU  5
NUM       EQU  COUNT+5

2.地址表达式

eg:
ADR1  EQU  DS[BP+14]
ADR1
被定义为在DS数据段中以BP作基址寻址的一个存储单元。

3.变量、寄存器名或指令助记符

eg:CREG  EQU  CX;在后面的程序使用CREG就是使用CX

        CBD     EQU  DAADAA为十进制调整指令。 

注意:在同一源程序中,同一符号不能用EQU定义多次。

二)等号语句

例如:

CONT=5

NUM=14H

NUM=NUM+10H

CBD=DAA

CBD=ADD

等号语句与等值语句具有相同的作用。但等号语句可以对一个符号进行多次定义。

注意:等值语句与等号语句都不会为符号分配存储单元。因此所定义的符号没有段、偏移量和类型等属性。

三)接触定义伪指令PURGE

格式:PURGE <符号1,符号2…,符号n>

功能:解除指定符号的定义

Y1 EQU 7

                PURGE Y1

                Y1 EQU 128

四)数据定义伪指令

1.常数

常数在汇编期间其值已完全确定,并且在程序运行过程中,其值不会发生变化。

1.二进制数:以字母B结尾,如01001001B
2.
八进制数:以字母OQ结尾,如631Q  254O
3.
十进制数:以字母D结尾,或者没有结尾字母。如2007D2007。
4.
十六进制数:以字母H结尾,如3FEH,如果常数的第一个数字为字母,为了与标识符加以区别,必须在其前面冠以数字“0”
5.实数。一般格式为:


例   2.134 E +10
6.字符串常数:用引号(单引号或双引号)括起来的一个或多个字符,这些字符以它的ASCII码值存储在内存。
        

2.变量
1.变量的定义与预置

格式: [变量名] 伪操作 操作数[,操作数,…]
功能:为操作数分配存储单元,用变量与存储单元相联系
重点是:DB,DW;注意:使用DT助记符时,对于10进制操作数,必须给出后缀D,没后缀则默认为压缩BCD码。

2.变量属性

段属性:他表示变量存放在哪一个逻辑段中。

偏移量属性(OFFSET):表示变量所在位置与段起始点之间的字节数。

类型属性:表示变量占用存储单元的字节数。

操作数:

(1)常数(代表数据)
字节数据 :a db 18h,-1,30 (2个16进制=8位)
字数据:a dw 18h,2a45h (4个16进制=16位)
双字数据: a dd 18h,2f3a124bh (8个16进制=32位)
表达式(代表内存单元地址):
word dw next
word dd next :偏移地址在段地址前面


(2)字符串(存放各字符的ASCAII码。注意:字符多于2个时,只能使用DB定义)
eg:

STR1 DB ‘A’, ‘B’, ‘C’, ‘D’
STR1 DB ‘ABCD’
?(只分配单元,不定义初值)
(3)DUP(复制操作符,表示操作数重复若干次)


eg:
嵌套使用:
BUF1 DB 2 DUP(2,3,4)
BUF1=2,3,4,2,3,4

BUF2 DW 1,2,3 DUP(6)
BUF2=1,2,6,6,6

DATA_A  DB   10H  DUP(?):分配16个字节

DATA_B  DB   20H  DUP(‘AB’):分配20H*2个字节因为有两个字符。

3.变量的使用

(1)在指令语句中引用

在指令语句中直接引用变量名就是对其存储单元的内容进行存取

(2)变址寻址或基址寻址或基址变址寻址

当变量出现在变址(基址)寻址或基址变址寻址的操作数中时表示取用该变量的偏移量。

(3)伪指令

3.标号

标号写一条指令的前面,它就是该指令在内存的存放地址的符号表示,也就是指令地址的别名。

属性:

段属性(SEG):表示标号所代表的地址在哪个逻辑段中,即段基址。

偏移量属性(OFFSET):他表示该标号所代表的地址在段内与段起点间的字节数,即地址的偏移量。

距离属性:表示该标号可以被段内还是段间的指令调用。

NEAR(近):标号只能做段内转移。指令标号只能在同一个逻辑段内。

FAR(远)可以被非本段的转移和调用指令使用。

如何定义NEAR,FAR?

(1)隐含方式:

(2)LABEL伪指令给标号指定距离属性

4、关系运算符

关系运算符包括:EQ(等于)、NE(不等于)、LT(小于)、 LE(小于等于)、GT(大于)、 GE(大于等于)

如果是常量的比较,则按无符号数进行比较;
如果是变量的比较,则
比较它们的偏移量的大小。

5.数值返回运算符

(1)SEG运算符

作用:去变量或标号所在端的段基值。

(2)OFFSET运算符

作用:该运算符的作用是去变量或标号在段内的偏移量

  • MOV BX, VAR2:将 VAR2 的内容(数据)复制到 BX 寄存器中。
  • MOV SI, OFFSET VAR2:将 VAR2 的偏移量复制到 SI 寄存器中。
  • MOV DI, ADDR:将 ADDR 存储的内容(即 VAR2 的偏移量)复制到 DI 寄存器中。
  • MOV BP, OFFSET ADDR:将 ADDR 的偏移量复制到 BP 寄存器中。
(3)TYPE<变量或标号>

作用:计算出变量的类型值或标号的类型值:

eg:

结果:

(4)LENGTH运算符

运算符只能加在变量的前面。如果变量是用重复数据操作符DUP说明的,则返回外层DUP给定的值。如果没有用DUP说明,则返回值总是1

(5)SIZE运算符

该运算符只能作用于变量,SIZE取值等于LENGTHTYPE两个运算符返回值的乘积。

6.属性修改运算符

1.PTR运算符

格式:类型   PTR   地址表达式

作用: 将地址表达式所指定的标号、变量或用其它形式表示的存储器地址的类型属性修改为 “类型”所指的值。
类型可以是
BYTEWORDDWORDNEARFAR。这种修改是临时性的,只在含有该运算符的语句内有效。

2.HIGH/LOW运算符

格式:(这两个运算符用来将一个数据分离出高字节和低字节)

HIGH  表达式

 LOW  表达式

如果表达式为一个常量,则将其分离成高8位和低8位;
如果表达式是一个地址(段基值或偏移量)时,则分离出它的高字节和低字节。

eg:

注意HIGH/LOW运算符不能用来分离一个变量、寄存器或存储器单元的高字节与低字节

3、THIS运算符

THIS运算符一般与等值运算符EQU连用,用来定义一个变量或标号的类型属性。所定义的变量或标号的段基值和偏移量与紧跟其后的变量或标号相同。

eg:
DATA_BYTE  EQU   THIS  BYTE
DATA_WORD  DW   10 DUP (0)

               ……
             MOV   AX, DATA_WORD
             MOV    BL, DATA_BYTE
               …...

eg2:
LFAR      EQU    THIS  FAR
LNEAR
MOV   AXB

习题:

数据格式不匹配,因为DA1是一个字节(只有8位),AX有16位。


BUF1=0,1,2,1,2,3,0,1,2,1,2,3,0,1,2,1,2,3(18个字节)
COUNT EQU $-BUF1 是汇编中的一个伪指令,用于计算从 BUF1 到当前汇编位置的字节数,并将结果赋值给符号 COUNT

  1. ORG 0120H 这条指令设定代码的起始地址为0120H

  2. VARA DW 10H,15H,$+24H 这条指令定义了一个叫VARA的数据段,并存储了三个数据:

    • 10H
    • 15H
    • $+24H是当前位置加上24H,即0124H(当前位置)+24H=0148H
    • 地址0120H0121H的内容是10H
      地址0122H0123H的内容是15H
      地址0124H0125H的内容是48H(因为0148H的高字节是00H,低字节是48H

MOV AH,BYTE PTR VARA+4 这条指令将VARA起始地址偏移4个字节的内容移动到AH寄存器。
VARA起始地址是0120H,偏移4字节后是0124H。 地址0124H的内容是0148H的低字节部分,即48H

  • 'BA':ASCII 码是 42H 和 41H。由于 DW 是存储两个字节(一个字),因此 'BA' 将被存储为 4241H(大端格式)。
  • 'DC':ASCII 码是 44H 和 43H。'DC' 将被存储为 4443H。
  • 'FE':ASCII 码是 46H 和 45H。'FE' 将被存储为 4645H。
    将这些数据按字节展开
    41H, 42H, 43H, 44H, 45H, 46H

20H个字节是32个字节

四、断定义伪指令

一)段定义伪指令

伪指令SEGMENTENDS用于定义一个逻辑段。使用时必须配对,分别表示定义的开始与结束。

一般格式:
 

段名   SEGMENT   [定位类型] [组合类型] [‘类别名']

            本段语句序列

段名    ENDS

1.段名
2.定位类型

定位类型用于决定段的起始边界,即第一个可存放数据的位置(不是段基址)。它可以有4种取值。
1PAGE:  表示该段从一个页面的边界开始。
(2)PARA:表示该段从一个小节的边界开始。
3WORD:表示该段从一个偶数字节地址开始,即段起始单元地址的最后一位二进制数一定是0。
4BYTE:表示该段起始单元地址可以是任一地址值
注意:定位类型为PAGEPARA时,段起始地址与段基址相同。定位类型为WORDBYTE时,段起始地址与段基址可能不同。

3.组合类型

二)指定段寄存器伪指令

格式: ASSUME <段寄存器名>:<段名>[,<段寄存器名>:<段名>…]
功能:建立段寄存器与段的缺省关系
含义:在程序的代码段开始处进行DS、SS、ES的段基址装填
mov ax,data
mov ds,ax
注意: ASSUME伪指令并为段寄存器(CS,SS)设定初值


三)过程定义伪指令(PROC/ENDP)

NEAR过程只能被本段指令调用,而FAR过程可以供其它段的指令调用.

每一个过程中必须包含有返回指令RET,其作用是控制CPU从子程序中返回到调用该过程的主程序。

四) 地址计数器$的使用

含义:表示下一个可用单元的地址
应用:常用来确定数组中元素的个数
例:
BUF1 DB 1,2,3,4,5
CNT1 EQU $-BUF1 (常用)
BUF2 DW 1,2,3,4,5

五)定位伪指令ORG

--用来改变位置计数器的值

格式:ORG 数值表达式

作用:将数值表达式的值赋给当前位置计数器。ORG语句为其后的数据或指令设置起始偏移量。

表达式的值必须为正值。表达式中也可以包含有当前位置计数器的现行值$

六)标题伪指令TITLE

格式:TITLE标题名
作用:给所在程序指定一个标题。以便在列表文件的每一页的第一行都显示这个标题。其中标题是用户任意选用的字符串,字符个数不能超过60

七)从程序返回操作系统的方法

1.使用DOS系统功能调用实现返回

执行DOS功能调用4CH,也可以控制用户程序结束,并返回DOS操作系统。
具体方法是在程序结束时,使用两条指令:
MOV  AH
4CH
INT     21H

例题

【例1】求字存储单元中两个数之差,结果存入下一个相邻的字单元中。

NAME  EXAMPLE   ;这条指令给程序命名为 EXAMPLE

DATA   SEGMENT

BUF    DW 3483H,4596H

RES    DW  ?  

DATA   ENDS

STACK  SEGMENT STACK STACK

       STA  DW 100 DUP(?)

STACK  ENDS

CODE   SEGMENT

       ASSUME CS:CODE.DS:DATA

 START:MOV AX,DATA             

       MOV DS,AX

       MOV AX,BUF

       SUB AX,BUF+2    ;AX 寄存器的当前值中减去 BUF+2 处的值。BUF3483HBUF+24596H(因为每个 DW 占用 2 个字节),所以这条指令实际上计算 3483H - 4596H

       MOV RES,AX      ;将结果存到RES中

       MOV AH,4CH       ;结束程序并返回操作系统

       INT  21H                                

CODE  ENDS

END   START

【例2】三个数相加并把结果存放在SUM单元中

DATA  SEGMENT

   BUF   DB 35H,78H,0A5H

   SUM   DB ?                   

   DATA  ENDS

   CODE  SEGMENT

               ASSUME CS:CODE,DS:DATA

 ASUM  PROC FAR

 START:PUSH DS

               MOV AX,0

               PUSH AX

               MOV AX,DATA

               MOV DS,AX

              MOV AL,0

              MOV SI,OFFSET BUF    ;将BUF的偏移地址存到SI中

               ADD AL,[SI]     ;AL+[SI]中的值,存到AL

               INC SI           ;下一个[SI]的值

               ADD AL,[SI]

               INC SI

               ADD AL,[SI]

               MOV SUM,AL

               RET          ;返回指令

  ASUM  ENDP

  CODE  ENDS

               END START

五、DOS功能子程序调用

调用过程:

送入口参量给指定寄存器
AH<=功能号
INT 21H

1、带显示的键盘输入(1号功能)
            MOV  AH01H
            INT     21H 
出口参数:AL = 读到字符的ASCII码

 2、字符串输入(0AH号功能)

    该功能调用可实现从键盘输入一个字符串
入口参数: DS:DX = 输入缓冲区首地址
出口参数:接收到的输入字符在缓冲区中

3、单个字符显示(2号功能)

功能实现在屏幕上显示单个字符。

入口参数:DL<=要显示字符的ASCII码。

例如:MOV   DL,‘A’

            MOV AH2

            INT  21H

4、字符打印(5号功能)

该功能将字符送入打印机接口,实现单个字符的打印操作。

入口参数:DL<= 打印字符的ASCII

MOV   DL,‘A’ 
MOV  AH
5     
INT     21H

5、字符串显示(9号功能)

该功能实现将一个字符串显示到屏幕上。

入口参数:

1)将待显示的字符串存放在一个数据缓冲区,字符串以符号“$”作为结束标志。

 (2)将字符串的首址的段基值和偏移量分别送入DSDX

6、不带显示的键盘输入(8号功能)
           MOV  AH,8
           INT    21H

7、不带显示的键盘字符输入(7号功能)

       MOV AH,7

       INT   21H

8、直接输入输出(6号功能)

      该功能可以实现键盘输入,也可以实现屏幕显示操作。两种操作通过DL的内容确定。
DL中是所显示字符的ASCII码。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值