汇编学习笔记(一)

一.寻址方式
立即寻址:
MOV AX,1234H
MOV AL,5
MOV BX,3064H

寄存器寻址:
可为AX/BX/CX/DX/SI/DI/SP/BP/AL/AH/BL/BH/CL/CH/DL/DH
MOV AX,BX

直接寻址:
有效地址即偏移地址
MOV AX,[8054] 默认DS 段前缀
可用符号地址代替数值地址
注意:MOV AX,VALUE等价于MOV AX,[VALUE]

寄存器间接寻址:
操作数有效地址在SI DI BP BX
SI/DI/BX默认是DS(数据段)
BX默认是SS
MOV AX,[SI]
可用段前缀 MOV AX.ES:[BX]

寄存器相对寻址:
操作数的有效地址是一个基址寄存器(BX,BP)或变址寄存器(SI,DI)的内容加上指令中给定的8位或16位位移量之和
PA = DS*16+BX/SI/DI+位移量
PA = SS*16+BP+位移量
MOV AX,[DI+1223H]
MOV AX,[SI+3]等价于MOV AX,3[SI]

基址加变址:
操作数有效地址由基址寄存器之一的内容+变址寄存器之一的内容
MOV AX,[BX][DI]等价于MOV AX,[BX+DI]
适合表格或数组处理

相对基址加变址:
操作数有效地址由基址寄存器之一的内容+变址寄存器之一的内容+指令给定的8位或16位位移量
指令中给定8位或16位位移量采用补码表示
如果位移量是8位,那么被带符号扩展成16位
如果超过FFFFH时就取其64K的模
MOV AX,[BX+DI+1234H]等价于MOV AX,1234H[BX+DI]等价于MOV AX,1234H[BX][DI]

二.指令语句
[标号:] 指令助记符 [操作数] [;注释]

三.指令功能
1.数据传送指令:
又分传送指令和交换指令
(1)传送指令:
   MOV DST,SRC
 (a)CPU寄存器之间的数据传送
 注意:源和目的操作数不能同时是段寄存器,代码段CS不能作为目的操作数
 指令指针IP既不能作为源,也不能作为目的
 (b)立即数送至通用寄存器或存储单元
 注意:立即数不能直接传送到段寄存器,立即数不能作为目的操作数
 (c)寄存器与存储器间的数据传送

注意:
源操作数和目的操作数类型要一致,8位与16位不能互传
两个操作数必须有一个寄存器(除了立即寻址),不能同时为存储器

如果要在两个存储单元间传送数据,可利用通用寄存器过渡的方法进行,如:
MOV AX,VARW1
MOV VARW2,AX
若MOV VARW2,VARW1 ;错误
这种方法也适用于段寄存器间的数据传送。

MOV BX,OFFSET TABLE ;把TABLE的偏移地址(不是内容)送到BX寄存器中,
OFFSET是属性操作符。

MOV指令不影响标志位。
(2)交换指令
  XCHG OPRD1,OPRD2
  OPRD1,OPRD2不能是段寄存器,不能是立即数,也不能同时是存储单元。
  同时是字节或者同时都是字。
  不影响标志位。
 
(3)地址传送指令
  8086/8088有三条地址传送指令
 (a)指令LEA : 传送有效地址指令
   LEA  REG,OPRD ;该指令把操作数OPRD的有效地址(偏移地址)传送到操作数REG
   操作数OPRD必须是一个存储器操作数,操作数REG必须是一个16位的通用寄存器
   与OFFSET区别,OFFSET是编译器 LEA是执行期
 (b)LDS 段值和段内偏移构成32位的地址指针,该指令传送32位地址指针
     LDS REG,OPRD
     执行的操作:(REG)<-- (SRC)
                  (DS) <--(SRC+2)
     该指令把操作数OPRD中所含的一个32位地址指针的段值部分送到数据段寄存器DS,
     把偏移部分送到指令给出的通用寄存器REG。
     OPRD必须是一个32位的存储器操作数,REG可以是16位通用寄存器,但实际使用
     往往是变址寄存器或指针寄存器。
    
     例子:
     LDS SI,[10H] 指令执行前(DS)= C000H,(C0010H)=0180,(C0012H) = 2000H
     指令执行后(SI) = 0180H,(DS) = 2000H
  (c)LES
     同LDS区别:将段值送到附加寄存器ES。
 (4)堆栈操作指令
    堆栈是一段RAM区域。称为栈底的一端地址较大(高地址),称为栈顶的一端地址较小(低地址)。
    堆栈指针寄存器SP始终指向栈顶。
    堆栈指令分两种:
    (a)进栈指令PUSH
       PUSH SRC
       执行的操作:SP<--(SP)-2
       该指令把源操作数SRC压入堆栈,它先把堆栈指针寄存器SP的值减2,
       然后再把源操作数SRC送入SP指向的栈顶。
       SRC可以是通用寄存器和段寄存器,也可以是字存储单元。
   (b)出栈指令 POP
       POP DST
       (SP)<--(SP)+2
       该指令从栈顶弹出一个字数据到目的操作数DST,然后SP+2
       DST可以是通用寄存器和段寄存器(除CS),也可以是字存储单元,但不能是立即数。
           
       注意,PUSH POP只能是字操作。此两条指令都不影响标志位。
      
       例:假设(SS)=2250,(SP)=0140,在堆栈中存入五个数据,那么栈顶的无聊地址是多少?
       未存入数据之前物理地址:22500+0140=22640H
       存入5个数据后:22640-0A=22636H
       注意这里5个数据占10个字节(5个字),因此减去0A。
      
 (5)标志操作指令:
  (a)标志传送指令:
        指令LAHF
        该指令把标志寄存器的低8位(包括SF,ZF,AF,PF,CF)传送到寄存器AH的指定位。
       
        指令SAHF
        与LAHF相反,将AH的指定位送至标志寄存器的低8位的SF,ZF,AF,PF,CF
        OF DF IF TF SF ZF  AF PF CF
        11 10  9  8  7  6   4  2  0
       
        指令PUSHF
        把标志寄存器的内容压入堆栈
       
        指令POPF
        把当前堆栈顶的一个字传送到标志寄存器。
       
 (b)标志位操作指令
     仅对指令规定的标志产生影响,对其他标志没有影响
     (1)清进位标志指令CLC
     (2)置进位标志指令STC
     (3)进位标志取反指令CMC
     (4)清方向标志CLD
     (5)置方向标志STD
     (6)清中断允许标志CLI
     (7)置中断允许标志STI
    
2.加减运算指令
 (1)加法指令 ADD
   ADD OPRD1,OPRD2
   (OPRD1)<--(OPRD1)+(OPRD2)
 注意:
 OF位根据操作数的符合及其变化情况来设置:若两个操作数的符号相同而结果
 的符号与之相反时OF=1,否则OF=0
 CF位可以用来表示无符号数的溢出。由于无符号数的最高有效位为数值位非符号位。
 所以从该位产生的进位应该是结果的实际进位。
 
  ADD指令影响标志位。
 
 (2)带进位加指令 ADC
   ADC OPRD1,OPRD2
  OPRD1<--OPRD1+OPRD2+CF
   
  实现双精度数加法,必须使用两条指令。
  使用ADC指令以便把前一条ADD指令作低位字加法所产生的进位值加入高位字之内。
  另外,带符号的双精度数的溢出,应该根据ADC指令的OF位来判断,而作低位加法
  用的ADD指令的溢出是无意义的。
  
 (3)加1指令INC
  INC OPRD
  影响ZF,SF,OF,PF,AF,不影响CF
  主要用于调整地址指针和计数器。
  
  
例子:写出把首地址为BLOCK的字数组的第6个字送到DX寄存器的指令
(1)寄存器间接寻址:
   MOV BX,OFFSET BLOCK ;或LEA BX,BLOCK
   ADD BX,000AH
   MOV DX,[BX]
(2)寄存器相对寻址:
   MOV BX,OFFSET BLOCK
   MOV DX,[BX+000AH]
   
  
   (4)减法指令SUB
      SUB OPRD1,OPRD2
      (OPRD1)<---(OPRD1)-(OPRD2)
      CF OF类似于加法指令
   
   (5)带借位的减法SBB
     SBB OPRD1,OPRD2
     (OPRD1)<---(OPRD1)-(OPRD2)-CF
     
   (6)减1指令DEC
     DEC OPRD
     同INC,不影响CF
     主要用于调整地址指针和计数器。
     
  (7)取补指令NEG
       NEG OPRD ;用零减去操作数OPRD,再把结果送回OPRD
       对-128取补,或在字操作时对-32768取补,则操作数不变,但OF被置为1,其他情况均为0.
       对0求补,CF=0,其他情况为1。
    
  (8)比较指令CMP
     CMP OPRD1,OPRD2
     OPRD1,OPRD2不能同时为存储单元。
     比较结果不送到OPRD1,但影响标志CF,ZF,SF,OF,AF和PF
    执行了比较指令后,如果ZF为1,则两者相等
    如果两者是无符号数,则可根据CF判断大小
    如果两者是有符号数,则要根据SF和OF判断大小      
      
例子:
设X,Y,Z均为双精度数,他们分别存放在地址为X,X+2,Y,Y+2,Z,Z+2的存储单元中,存放时高位字节
在高地址中,低位字在低地址中。用指令实现 W<--X+Y+24-Z

MOV AX,X
MOV DX,X+2
ADD AX,Y
ADC DX,Y+2
ADD AX,24
ADC DX,0
SUB AX,Z
SBB DX,Z+2
MOV W,AX
MOV W+2,DX

例子:写出对存放在DX和AX中的双字长数求补的指令序列
 NEG DX ;必须先对高位求补
 NEG AX
 SBB DX,0
 
例子:指出下列指令的错误:
a.MOV AX,[SI][DI]
b.CMP 15,BX
c.PUSH BL
d.POP CS
e.CMP OP1,OP2(OP1,OP2都为字节变量)
f.CMP AX,OP1
答:
a.必须一个为基址一个为变址
b.立即数不能作为目的数
c.堆栈操作指令都以字为单位,必须是字操作
d.代码段不能做目的操作数
e.两个操作数不能都为存储单元
f.一个为字一个为字节


3.乘除运算指令
乘除运算指令分为无符号数运算和有符号数运算指令
对标志位影响有些特别
(1)乘法指令
 一个操作数总是隐含在寄存器AL(8位相乘)或AX(16位相乘)中,
 另一个操作数可以采用除立即数以外的任一种寻址方式。
 在乘法指令中,目的操作数必须是累加器
 (a)无符号数乘法指令
  MUL OPRD
  两个8位数的16位乘积存放在AX中,两个16位数的32位乘积存放在DX、AX中,
  DX存放高位字,AX存放低位字。
  如果乘积结果的高半部分不等于零,则CF=1,OF=1.否则都为0.
  该指令对其他标志位无定义。
  
 (b)有符号数乘法指令 IMUL
   IMUL OPRD
 如果乘积结果的高半部分不是低半部分的符号扩展,则标志CF=1,OF=1;否则都为0
 
(2)除法指令
  一个操作数总是隐含在寄存器AL(除数是8位)或AX(除数是16位)中,
 另一个操作数可以采用除立即数以外的任一种寻址方式。
 字节操作(AX/OPRD(8位))商放在AL中,余数放在AH中
 字操作((DX,AX)/OPRD(16位))商放在AX中,余数放在DX中
 (a)无符号数除法指令DIV
  DIV OPRD
  如果除数为0,或者在8位数除时商超过8位,或者在16位除时商超过16位。则认为是除溢出。
  引起0号中断。
  除法对标志位的影响无定义。
  
 (b)有符号数除法指令IDIV
 当除数为0,或者商太大(字节时超过127,字除时超过32767),或者商太小(字节时小于-127,
 字除时小于-32767),引起0号中断。
 
(3)符号扩展指令
   (a)字节转换为字指令CBW(CONVERT BYTE TO WORD)
      格式: CBW ;把寄存器AL中的符号扩展到寄存器AH
例子: MOV AX,3487H ;AX = 3487H,AH = 34H,AL = 87H
          CBW ;AL=10000111 AH-->1111111110000111
        
      该指令不影响各标志位。
     
   (b)字转换为双字指令CWD(CONVERT WORD TO DOUBLE)
      CWD ;把寄存器AX中的符号位扩展到寄存器DX
      不影响各标志位
     
例子:计算如下表达式的值:(X*Y+Z-1024)/75
假设其中的X,Y,Z均为16位带符号数,分别存放在名为XXX,YYY和ZZZ的变量单元中
再假设计算结果的商保存在AX中,余数保存在DX中。

MOV AX,XXX
IMUL YYY
MOV CX,AX  ;低8位保存在CX
MOV BX,DX  ;高8位保存在BX
MOV AX,ZZZ
CWD        ;把ZZZ扩展为32位
ADD AX,CX
ADC DX,BX
SUB AX,1024  ;立即数无需位扩展
SBB DX,0
MOV CX,75
IDIV CX

4.逻辑运算和移位指令
(1)逻辑运算指令
 (a)否操作指令NOT
  NOT OPRD
  这条指令把操作数OPRD取反,然后送回OPRD
  OPRD不能为立即数
  对标志位无影响
  
  (b)与操作数AND
     AND OPRD1,OPRD2 ;该指令对两个操作数进行按位的逻辑与运算,结果送到目的操作数OPRD1
     该指令执行后,标志CF=0,OF=0.标志PF,ZF,SF反映运算结
     果,AF未定义
     某个操作数与自己相与,则值不变,但CF清0
    
  (c)或操作指令OR
    OR OPRD1,OPRD2
    该指令执行后,标志CF=0,OF=0.标志PF,ZF,SF反映运算结
      果,AF未定义
      某个操作数与自己相或,则值不变,但CF清0
     
  (d)异或操作指令
      该指令执行后,标志CF=0,OF=0.标志PF,ZF,SF反映运算结
      果,AF未定义
      某个操作数与自己相异或,则结果为0,并可使CF清0
     
  (e)测试指令TEST
    TEST OPRD1,OPRD2
    与AND类似,但是结果不回送。
    该指令执行后,标志CF=0,OF=0.标志PF,ZF,SF反映运算结
      果,AF未定义
      通常用于检测某些位是否为1,但又不希望改变原来的操作数。
例:要检查AL中的位6或位2是否有一位为1:
TEST AL,01000100B ;符号B表示二进制
 如果位6和位2全为0,那么执行上面指令后ZF被置为1.否则ZF被清0。
 
 (2)一般移位指令
   (a)算术左移或逻辑左移指令SAL/SHL
     算术左移和逻辑左移进行相同的动作,虽然有两个助记符,但是只有一条机器指令。
   SAL OPRD,m  ;一般用于有符号数
   SHL OPRD,m  ;一般用于无符号数
   执行的操作相同,将操作数OPRD左移m,每移动一位一位,右边补足0
   移出的最高位进入标志位CF
   MOV AL,8CH
   SHL AL,1  ;A=18H,CF=1,PF=1,ZF=0,SF=0,OF=0
   MOV CL,6 ; CL=6
   SHL AL,CL ;AL=0,CF=0,PF=1,ZF=1,SF=0,OF=0
   注意,如果m大于1,则必须先将m存入CL中。
   溢出标志位OF只有当m=1时菜有效,如果m>1则OF无效,始终为0。
   每左移一次相当于元素乘2(如果未溢出)。
例子:
实现把寄存器AL中的内容(设为无符号数)乘10,结果存放在AX中
XOR AH,AH ;(AH)=0 先将AH清零
SHL AL,1  ;2X
MOV BX,AX  ;暂存2X
SHL AX,1 ;4X
SHL AX,1 ;8X
ADD AX,BX ;8X+2X
   
  (b)算术右移指令SAR
      SAR OPRD,m
      该指令使操作数右移m位,每移一位,注意:左边符号位不变,移出的最低位
      进入标志位CF。
      m>1时,必须先把m存到CL
      MOV CL,5
      SAR [DI],CL
     
  (c)逻辑右移指令SHR
       SHR OPRD,m
       右移m位,左边用0补足。移出最低位进入标志位CF
例子:假设DATA1和DATA2各长4位,分别存放于AL寄存器的低4位和高4位中,现在要把他们分别
存放在BL寄存器和BH寄存器的低4位中
MOV BL,AL
AND BL,OFH ;得DATA1
MOV BH,AL
MOV CL,4
SHR BU,CL

   (3)循环移位指令
   这些指令可一次只移一位,也可以一次移多位。
   如果移多位,那么移位次数存放在CL寄存器中。
  
   ROL OPRD,m ;循环左移
   ROR OPRD,m ;循环右移
   RCL OPRD,m ;带进位循环左移,影响CF和OF
   RCR OPRD,m ;带进位循环右移,影响CF和OF
   后两条循环指令把进位标志CF也包含在循环的环中,即作为整个循环的一部分
  
5.转移指令
 (1)无条件转移指令
  (a)无条件段内直接转移指令
    JMP 标号
    执行该指令实际操作是把指令中的地址差加到指令指针IP上,使IP的内容为目标地址。
    段内无条件直接转移指令中的地址差只用一个字节表示,就称为短转移。
    如果用一个字表示,则称为近转移。
    段内近跳转: JMP NEAR PTR PROG
    段内短跳转: JMP SHORT QUEST
    
  (b)无条件段内间接转移指令
     JMP OPRD
     转移到操作数OPRD的内容给定的目标地址处。
     OPRD可以是通用寄存器,也可以是字存储单元。
     例:JMP WORD PTR [2001H]
    
  (c)无条件段间直接转移指令
    JMP FAR PTR 标号
    例如 JMP FAR PTR NEXT
    NEXT是定义在另一个代码段中的标号
    实际操作:把指令中包含的目标地址的段值和偏移分别置入CS和IP
    
  (d)无条件段间间接转移指令
   JMP OPRD
   这条指令使控制无条件地转移到由操作数OPRD内容给定的目标地址处。OPRD必须为双字存储单元。
   双字存储单元低字内容送给IP,高字内容送给CS
   
 (2)条件转移指令
   根据某标志位或某些标志位的逻辑运算来判别条件是否成立。如果条件成立,则转移。
   有符号数间的次序关系称为大于G,等于E,小于L
   无符号数间的次序关系称为高于A,等于E,低于B
例子:实现两个无符号数(设在AX和BX中)的比较,把较大的数存放在AX中,把较小的BX中:
CMP AX,BX
JAE OK 
XCHG AX,BX
OK: ...

如果要比较的两个数是有符号数:
CMP AX,BX
JGE OK
XCHG AX,BX
OK:...

   两个数是否相等可由ZF标志反映。
   两个有符号数比较后大小关系由SF和OF一起反映。
   当没有溢出(OF=0),若SF=0,a>b
   当产生溢出(OF=1),若SF=0,a<b
   无符号数使用CF来判别大小关系。
例子:设X,Y均为存放在X和Y单元中的16位操作数,先判断X>50否,如满足条件则转移到TOO-HIGH 去执行,然后做X-Y,如溢出则转移到OVER
去执行,否则计算|X-Y|,并把结果存入RESULT中。
MOV AX,X
CMP AX,50
JG TOO-HIGH
SUB AX,Y
JO OVER
JNS DONE
NEG AX
DONE:MOV RESULT,AX
TOO-HIGH:..
OVER:...

例子:假设有100个16位无符号数存放在从1234:5678H
开始的内存中,现需要求他们的和。设把32位的和保存在DX(高位)和AX寄存器中。
   MOV AX,1234H
   MOV DS,AX  ;置数据段寄存器值
   MOV SL,5678H  ;置指针初值
   MOV AX,0   ;清零32位累加和
   MOV DX,AX
   MOV CX,100  ;置数据个数计数器
NEXT: ADD AX,[SI]  ;求和
   ADC DX,0  ;加上可能的进位
   INC SI
   INC SI
   DEC CX  ;计数器减1
   JNZ NEXT  ;如果不为0,那么继续累加
   
 (3)循环指令:
  循环指令转移的范围在-126至129之间。
  循环指令不影响各标志位。
  (a)计数循环指令LOOP:
   LOOP 标号
   该指令使寄存器CX的值减1,如果结果不为0,则转移到标号。否则顺序执行。
   最多可循环65536次。
例子:如下程序片段实现把从偏移1000H开始的512个字节的数据复制到从偏移3000H开始的缓冲区中。
   MOV SI,1000H  ;置源指针
   MOV DL,3000H  ;置目标指针
   MOV CX,512  ;置计数器初值
NEXT:MOV AL,[SI]
   INC SI
   MOV [DI],AL
   INC DI
   LOOP NEXT 
  
   (b)等于/全零循环指令LOOPE/LOOPZ
   LOOPE 标号
   LOOPZ 标号
   这条指令使寄存器CX的值减1,当为0或相等时(且ZF等与1),那么转移到标号
例子:字符串中查找第一个非‘A’字符,设字符串长度已保存在CX中,并且DS:DI指向字符串。
如果找到,那么使BX指向该非‘A’字符,如果未找到,那么使BX为0FFFFH
   MOV AL,'A'
   DEC DI
NEXT: INC DI
   CMP AL,[DI]
   LOOPE NEXT
   MOV BX,DI
   JNE OK
   MOV BX,-1
OK :...

  (c)不等于/非零循环LOOPNE/LOOPNZ
  如果结果不为0或不相等时,并且零标志ZF等于0,那么转移到标号,
  否则顺序执行,CX减1操作不影响标志。
  
  (d)跳转指令JCXZ
    JCXZ 标号
   该指令实现当寄存器CX的值等于0时转移到标号,否则顺序执行。
   通常该指令用在循环开始前,以便在循环次数为0时,跳过循环体
例子:
   JCXZ OK  ;如果循环计数为0,就跳过循环
NEXT:...  ;
....
LOOP NEXT
OK:...

例子:有一串L字符的字符串存储于首地址为TABLE的存储器中,如果要求在字符串中查找空格
字符,找到则继续执行,如未找到则转到NOT-FOUND去执行:
   MOV CX,L
   MOV SL,-1
   MOV AL,20H
NEXT: INC SI
    CMP AL,TABLE[SI]
    LOOPNE NEXT
    JNZ NOT-FOUND
    ...
NOT-FOUND: ...
   

你可能感兴趣的:(汇编,table,存储,扩展,编译器,DST)