一、数据传送类指令
- 通用传送指令——MOV
- mov指令并非任意传送:
- 源操作数和目的操作数不能同时为主存储器操作数
-
MOV DBUF2,DBUF1 ;错误 MOV AX,DBUF1 MOV DBUF2,AX ;正确
-
- 源操作数和目的操作数不能同时为段寄存器操作数
- 立即数不能直接传送给段寄存器
-
MOV DS, @DATA ;错误 MOV AX,@DATA MOV DS,AX ;正确
-
- 传送时双操作数必须类型一致
-
MOV SI,DL ;错误:类型不一致 SI16位,DL8位 MOV AL,050AH ;错误:类型不一致 050AH超过AL范围
-
- 操作数必须要有明确的类型
-
MOV [BX],255 ;错误:无明确类型 MOV BYTE PTR [BX] , 255 ;正确,byte ptr说明是字节操作
-
- 源操作数和目的操作数不能同时为主存储器操作数
- mov指令并非任意传送:
- 通用传送指令——XCHG
- 将源操作数和目的操作数的内容交换
- 可以使用于通用寄存器与通用寄存器之间或者通用存储器与存储器之间
- 例子:
XCHG SI,DI XCHG SI,[DI] XCHG AL,BVAR
- 空操作指令NOP(=XCHG AX,AX)
- 例子:
- 堆栈操作指令
- 只有一个数据出入口——当前栈顶
- 两种基本操作
- push
- SP-2作为当前栈顶
- 将源操作数(通用寄存器/段寄存内容/存储器操作数)传送到栈顶
- 以字为单位进行操作
- pop
- SP+2作为当前栈顶
- 将栈顶数据传送到目的操作数(通用寄存器/段寄存内容/存储器操作数)
- 以字为单位进行操作
- push
- SS指向堆栈段的起始位置(段基地址) SP指定栈顶
- 数据进入堆栈,SP逐渐减小
- 数据依次弹除,SP逐渐增大
- 堆栈的应用
- 堆栈操作指令
- 子程序调用CALL和返回RET
- 中断调用INT和返回IRET
- 内部异常、外部中断
- 存放临时数据,以便随时恢复
- 子程序的寄存器的保护和恢复
- 地址传送指令
- 获取存储器操作数的地址
- 格式:LEA R16,MEM
- 类似OFFSET的作用
- LEA在指令执行时计算出偏移地址
- OFFSET操作符在汇编阶段取得变量的偏移地址
- OFFSET无需在执行时计算,执行速度更快
- LEA能获取汇编阶段无法确定的偏移地址
- 例:
LEA SI,VAR MOV DI,OFFSET VAR ;等价
LEA DX,[BX+DI-100H] ;先进行加法运算得到偏移地址再传送给DX寄存器(相对基址变址寻址方式) MOV DX,OFFSET[BX+DI-100H] ;是错误的,因为汇编时不知道执行DX和DI等于什么
- 其他的:指针传送指令LDS和LES,能将主存连续四个字节内容的前两个分别传送给DS和ES后续字节作为偏移地址传送给指令的十六位通用寄存器。
- 换码指令
- XLAT指令功能:AL←[BX+AL]
- 指令执行前:
- 在主存建立一个字节量表格
- 表格首地址放于BX
- AL存放相对表格首地址的位移量
- 指令执行后:
- 将AL寄存器的内容转换为目标代码
- 指令执行前:
- 例:
;eg303.asm .model small .stack .data num db 6,7,7,8,3,0,0,0 tab db '0123456789' ;代码表 .code .startup mov cx,lengthof num ;CX等于要转换数字的个数 mov si,offset num ;SI指向要转换的数字 mov bx,offset tab ;BX指向代码表 again: mov al,[si] ;AL←要转换的数字 xlat ;换码,AL得到数字的ASCII值 mov dl,al ;显示 mov ah,2 int 21h add si,1 ;指向下一个数字 loop again ;循环 .exit end
- XLAT指令功能:AL←[BX+AL]
- 标志传送指令
- 可以直接改变CF、DF、IF状态的标志位操作指令
- 教材P73
- 输入输出指令
- 输入指令IN:数据从IO接口输入到微处理器
- IN AL,21H
- IN AL,DX
- 输出指令OUT:数据从微处理器输出IO接口
- OUT 21H,AL
- OUT DX,AL
- IO寻址方式:直接寻址&DX间接寻址
- 直接寻址由IO指令直接提供8位IO地址 只能寻址最低256个IO地址 用i8表示
- 间接寻址用DX寄存器保存访问的IO地址 可以寻址全部IO地址(0000~FFFFH) 直接写成DX,表示IO地址
- 8位IO传输:IO指令使用AL
- 16位IO传输:IO指令使用AX
- 输入指令IN:数据从IO接口输入到微处理器
二、算数运算类指令
- 状态标志
- CF 进位标志 针对无符号数
- 当加减法运算结果的最高有效位有进位或借位 CF=1
- N个二进制位表达无符号整数的范围:0~pow(2,N)-1
- 有进位加上进位或借位后结果仍然正确
- OF 溢出标志 针对有符号数
- 加减结果有溢出 OF=1
- N个二进制位(补码)表达有符号整数的范围:-pow(2,N-1)~pow(2,N-1)-1
- 有溢出,运算结果已经不正确
- 判断:
- 最高位和次高位同时有进位或同时无进位,无溢出;最高位和次高位进位状态不同,有溢出
- 只有两个相同符号数数相加(或两个不同符号数相减),而运算结果的符号与原数据符号相反时产生溢出,其他情况无溢出。
- ZF 零标志
- 运算结果位0,ZF=1
- SF 符号标志
- 运算结果最高位为1,SF=1
- PF 奇偶标志
- 运算结果最低字节(最低8位)中“1”的个数为零或偶数,PF=1
- AF 辅助进位标志/调整标志
- 最低半字节有进位或借位时,AF=1
- 查看状态标志方法:
-
PUSHF;将标志寄存器的值入栈 POP AX;将标志寄存器的值出栈赋值给AX
-
- CF 进位标志 针对无符号数
- 加法指令
- ADD
- 双操作数。目的操作数加上源操作数,和送回目的操作数
- 按照定义影响六个状态标志位
- ADC
- 两个操作数相加再加CF,结果送回目的操作数
- 按照定义影响六个标志位
- INC
- 一个操作数,实现对操作数自增一,再将结果返回原处
- 不影响CF,但影响其他标志位
- ADD
- 减法指令
- SUB
- 目的操作数减去源操作数,结果送回目的操作数
- 按照定义影响六个标志位
- SBB
- 除完成SUB减法运算外,还要减去借位CF,结果送回目的操作数
- 按照定义影响六个标志位
- DEC
- 对操作数减一再将结果返回原处
- 不影响CF,但影响其他标志位
- NEG
- 求补指令 单操作数
- 用零减去操作数,将结果返回操作数
- 按照定义影响六个标志位
- CMP
- 将目的操作数减去源操作数,差值不送回。
- 按照减法结果影响标志
- SUB
- 乘法指令
- MUL/IMUL(无符号数/有符号数)
- 隐含使用目的操作数AX
- 源操作数为8位数:AL与其相乘得到16位积,存入AX
- 源操作数为16位:AX与其相乘得到32位积,高16位存入DX,低16位存入AX
- 对标志的影响:
- 若乘积的高一半是低一半的符号位扩展,说明高一半不含有效数值,则OF=CF=0
- 若高一半有效,则OF=CF=1
- 乘法指令对其他标志状态没有定义,即为任意,不可预测
- MUL/IMUL(无符号数/有符号数)
- 除法指令
- DIV/IDIV(无符号数/有符号数)
- 隐含使用目的操作数AX
- 8位除法:AL=AX÷源操作数的商,AH=AX÷源操作数的余数
- 16位除法:AX=DX.AX÷源操作数的商,DX=DX.AX÷源操作数的余数
- DIV/IDIV(无符号数/有符号数)
- 符号扩展指令
- CBW :AL扩展到AX
- CWD:AX扩展到DX.AX
三、位操作类指令
- 逻辑运算指令
- AND
- 同0与 复位
- OR
- 同1或 置位
- NOT
- XOR
- “与1异或取反,与0异或不变”
- 最快的将寄存器清零的方法:XOR DX,DX
- TEST
- 将两个操作数按位进行逻辑与运算,不返回逻辑与的结果,根据结果像AND指令一样设置状态标志。
- 除NOT不影响标志外,其他逻辑指令讲OF=CF=0,按定义影响ZF、SF、PF
- AND
- 移位指令
- 移位
- shl 逻辑左移:左移1/CL位,最低位补零,最高位进入CF
-
;AL=1111 0101B SHL AL,1 ;AL=1110 1010B CF=1 ;OF=0
-
- shr 逻辑右移:右移1/CL位,最高位补零,最低位进入CF
-
;AL=1111 0101B SHR AL,1 ;AL=0111 1010B ;CF=1 OF=1
-
- sal 同shl
- sar 算数右移:右移1/CL位,最高位不变,最低为进入CF
-
;AL=1111 0101B SAR AL,1 ;AL=1111 1010B ;CF=1 OF=0
-
- 源操作数只能是1或者CL
- 根据最高或最低位移处的位设置CF
- 根据移位后的结果影响SF,ZF,PF
- 如果进行一位移动,按照操作数的最高符号是否改变设置溢出标志OF:
- 移位前最高位与移位后最高位不同:OF=1
- 移位次数不为1时OF不确定。
- 逻辑左移相当于乘二,逻辑右移相当于除二。 商在操作数中,余数由CF标志反映。
- shl 逻辑左移:左移1/CL位,最低位补零,最高位进入CF
- 循环移位
- rol 不带进位循环左移:左移1/CL位,最高位进入CF和最低位
-
;AL=1110 0101B ROL AL,1 ;AL=1100 1011 ;CF=1 OF=0
-
- ror 不带进位循环右移:右移1/CL位,最低位进入CF和最高位
-
;AL=1110 0101B CL=2 ROR AL,CL ;AL=0111 1001B ;CF=0
-
- rcl 带进位循环左移:左移1/CL位,最高位进入CF,CF进入最低位
-
;AL=1110 0101B CF=0 RCL AL,1 ;AL=1100 1010B ;CF=1 OF=0
-
- rcr 带进位循环右移:右移1/CL位,最低位进入CF,CF进入最高位
-
;AL=1110 0101B CL=4 CF=0 RCR AL,CL ;1 AL=0111 0010B CF=1 ;2 AL=1011 1001B CF=0 ;3 AL=0101 1100B CF=1 ;4 AL=1010 1110B CF=0
-
- rol 不带进位循环左移:左移1/CL位,最高位进入CF和最低位
- 移位
四、课后习题!
3.1 (1)如何修改"MOV SI,BYTE PTR 250"语句使其正确?
MOV SI,250
(2)为什么说“XCHG DX,CL"是一条错误的指令?
源寄存器操作数和目的寄存器操作数位数不同。
(5)执行了一条加法指令后,发现ZF=1,说明结果是什么?
0
(7)大小写字母转换使用了什么规律?
相差20H。
(9)除法指令”DIV SI"的被除数是什么?
被除数32位,DX保存高16位,AX保存低16位。
3.2 判断题
(1)指令“MOV AX,0”使AX结果为0,所以标志位ZF=1。
错,MOV XCHG不影响标志位
(4)虽然ADD指令和SUB指令执行后会影响标志状态,但执行前的标志并不影响它们的执行结果。
对。
(5)80-90需要借位,所以执行结束后,进位标志CF=1.
对。
(7)无符号数在前面加零扩展,数值不变;有符号数前面进行符号扩展,位数加长一位,数值增加一倍。
错。符号扩展不改变数值大小。有符号数的符号扩展扩展的是符号位。
(10)SHL指令左移一位,就是乘10.
错。是*2。
3.3 填空题
(1)指令"PUSH DX"执行后,SP -2 。
(2)指令"POP DX"的功能是将堆栈顶部的数据传送给 DX ,然后 SP+2 。
(4)进行8位的二进制数加法BAH+6CH,8位结果是 26H ,标志PF= 0 。如果进行16位二进制数加法45BAH+786CH,16位结果是 0BE26 ,标志PF= 0 。
(5)假设AX=98H,执行NEG AX指令后,AX= 0FF68H ,标志SF= 1 。
(8)指令“XOR AX,AX”和“SUB AX,AX”执行后,AX= 0 。CF=OF= 0 。而指令"MOV AX,0"执行后,AX= 0 ,CF和OF没有变化。
(10)欲将DX内的无符号数除以16,可以使用指令"SHR DX, CL ",其中后一个操作数是一个8位寄存器,其值等于 4 。
3.5 操作数的组合通常符合逻辑,但不是任意的,指出下列指令的错误原因:
(1)MOV CX,DL 位数不同(类型不匹配)
(2)MOV IP,AX IP为专用寄存器,不能赋值
(3)MOV ES,1234H 不能直接将立即数赋值给段寄存器
(4)MOV ES,DS 段寄存器之间不能赋值
(5)MOV AL,300 位数不同
(6)MOV [SI],45H 没有明确类型
(7)MOV AX,BX+DI 无该种寻址方式
(8)MOV 20H,AH 不能给立即数赋值
3.6 使用MOV指令实现交换指令“XCHG BX,[DI]”功能。
MOV AX,[DI]
MOV BX,AX
MOV [DI],BX
3.11 分别执行如下程序片段,说明每条指令的执行结果:
(1)
MOV AX,80H ;AX= 0080H ADD AX,3 ;AX= 0083H ,CF= 0 ,SF= 0 ADD AX,80H ;AX= 0103H ,CF= 0 ,OF= 0
ADC AX,3 ;AX= 0106H ,CF= 0 ,ZF= 0
(2)
MOV AX,100 ;AX= 64H ADD AX,200 ;AX= 12CH ,CF= 0
(3)
MOV AX,100 ;AX= 64H ADD AL,200 ;AX= 2CH ,CF= 1
(4)
MOV AL,7FH ;AL= 7FH SUB AL,8 ;AL= 77H ,CF= 0 ,SF= 0 SUB AL,80H ;AL= F7H ,CF= 1 ,OF= 1 SBB AL,3 ;AL= F3H ,CF= 0 ,ZF= 0
3.14 请分别用一条汇编语言指令完成如下功能:
(1)把BX寄存器和DX寄存器的内容相加,结果存入DX寄存器
ADD DX,BX
(2)用寄存器BX和SI的基址变址寻址方式把存储器中的一个字节和AL寄存器的内容相加,并把结果送到AL中。
ADD AL, [BX+SI]
(3)用BX和位移量0B2H的寄存器相对寻址方式把存储器中的一个字和CX寄存器的内容相加,并把结果送回存储器中。
ADD [BX+0B2H],CX
(4)将16为变量VARW与数3412H相加,并把结果送回该存储单元中。
ADD VARW,3412H
(5)把数0A0H与AX寄存器的内容相加,并把结果送回AX中。
ADD AX,0A0H
3.16 分别执行如下程序片段,说明每条指令的执行结果:
(1)
MOV SI,10011100B ;SI= 9C H AND SI,80H ;SI= 80 H OR SI,7FH ;SI= FF H XOR SI,0FEH ;SI= 1 H
(2)
MOV AX,1010B ;AX= 0000 0000 0000 1010 B MOV CL,2 SHR AX,CL ;AX= 0000 0000 0000 0010 B,CF= 1 SHL AX,1 ;AX= 0000 0000 0000 0100 B,CF= 0 AND AX,3 ;AX= 0000 0000 0000 0000 B,CF= 0
(3)
MOV AX,1011B ;AX= 0000 0000 0000 1011 B MOV CL,2 ROL AX,CL ;AX= 0000 0000 0010 1100B,CF= 0 RCR AX,1 ;AX= 0000 0000 0001 0110 B,CF= 0 OR AX,3 ;AX= 0000 0000 0001 0111 B,CF= 0
(4)
XOR AX,AX ;AX= 0 ,CF= 0 ,OF= 0 ;ZF= 1 ,SF= 0 ,PF= 1
3.21 如下程序片段实现AX乘以某个数X的功能,请判断X=?请使用一条乘法指令实现上述功能。
MOV SI,AX SHL SI,1 SHL SI,1 SHL SI,1 SUB SI,AX MOV AX,SI
答:本程序段相当于:AX*2*2*2-AX=AX*7
故X=7
使用一条乘法指令为:
mul ax,7
3.22请使用移位和减法指令编写一个程序片段计算:AX×21,假设乘积不超过16位。(提示:21=pow(2,4)+pow(2,2)+pow(2,0))。
答:
MOV SI,AX SHL SI,1 SHL SI,1 ADD AX,SI SHL SI,1 SHL SI,1 ADD AX,SI