作为汇编语言的课程笔记,方便之后的复习与查阅
本篇为课程第六次课内容
目录
- 算术运算指令
- 加法指令ADD
- 带进位加法指令ADC
- 增量指令INC(increment)
- 减法指令SUB(subtract)
- 带借位减法指令SBB
- 减量指令DEC(decrement)
- 求补指令NEG(negative)
- 比较指令CMP(compare)
- 符号扩展指令
- 乘法指令
- 除法指令
- DOS系统调用
- BIOS中断:字符属性
- BIOS中断:设定显示模式
- BIOS中断:置光标位置
- BIOS中断:在光标位置显示字符
- BIOS中断:显示字符串
算术运算指令
请注意算术运算类指令对标志的影响
- 掌握:ADD/ADC/INC、SUB/SBB/DEC/ NEG/CMP
- 熟悉:MUL/IMUL、DIV/IDIV
- 理解:CBW/CWD
加法指令ADD
add
指令将源与目的操作数相加,结果送到目的操作数。源操作数为立即数时,源操作数带扩展为和目的操作数相同长度类型
ADD reg,imm/reg/mem ;reg←reg+imm/reg/memADD mem,imm/reg ;mem←mem+imm/reg
注意:
- 源操作数和目标操作数类型匹配
- 目标不能是立即数和
CS
段寄存器
- 两个操作数不能同时为存储器操作数
- 对于
ADD mem,imm
的形式,要指明
mem
的长度类型(如:
BYTE PTR [100H]
)
示例:
ADD AL, 2050H ; 错误,AL寄存器为8位,而立即数为16位ADD AX, 50H ; 正确ADD AX, BL ; 错误,前后两个寄存器位数不同ADD 2050, AX ; 错误,目标操作数不能为立即数ADD CS, 2050H ; 错误,目标操作数不能为立即数CS段寄存器ADD [200H], 05H ; 错误,未指定内存单元的长度类型ADD BYTE PTR [200H], BYTE PTR [100H] ; 错误,不允许源操作数和目的操作数都为mem
ADD
指令按状态标志的定义相应设置:
CF
OF
SF
ZF
AF
PF
—- 重点理解对
CF
与
OF
的影响
注意:上面的数都是用补码表示的
带进位加法指令ADC
ADC
指令将源与目的操作数相加,再加上进位
CF
标志,结果送到目的操作数
ADC
指令主要与
ADD
配合,实现多精度加法运算
ADC reg,imm/reg/mem ;reg←reg+imm/reg/mem+CFADC mem,imm/reg ;mem←mem+imm/reg+CF
用汇编处理时最多只能处理16位的,在处理高16位加法的时候使用
adc
增量指令INC(increment)
INC
指令对操作数加1(增量),主要用于对计数器和地址指针的调整
INC
指令不影响进位
CF
标志,按定义设置其他状态标志
INC reg/mem ;reg/mem←reg/mem+1
inc bxinc byte ptr [bx]
减法指令SUB(subtract)
SUB
指令将目的操作数减去源操作数,结果送到目的操作数
SUB reg,imm/reg/mem ;reg←reg-imm/reg/memSUB mem,imm/reg ;mem←mem-imm/reg
注意:
- 源操作数和目标操作数类型匹配
- 目标不能是立即数和
CS
段寄存器
- 两个操作数不能同时为
mem
- 对于
SUB mem, imm
的形式,要指明
mem
的长度类型
SUB
指令按状态标志的定义相应设置:
CF
OF
SF
ZF
AF
PF
—- 重点理解对
CF
与
OF
的影响
带借位减法指令SBB
SBB
指令将目的操作数减去源操作数,再减去借位
CF
(进位),结果送到目的操作数
SBB
指令主要与
SUB
配合,实现多精度减法运算
SBB reg,imm/reg/mem ;reg←reg-imm/reg/mem-CFSBB mem,imm/reg ;mem←mem-imm/reg-CF
减量指令DEC(decrement)
DEC
指令对操作数减1(减量),主要用于对计数器和地址指针的调整
DEC
指令不影响进位
CF
标志,按定义设置其他状态标志
DEC reg/mem ;reg/mem←reg/mem-1
dec bxdec byte ptr [bx]
求补指令NEG(negative)
NEG
指令对操作数执行求补运算:用零减去操作数,然后结果返回操作数。求补运算也可以表达成:将操作数按位取反后加1
NEG
指令对标志的影响与用零作减法的
SUB
指令一样
NEG reg/mem ;reg/mem←0-reg/mem 例如:求0110 0100的补码就相当于计算1 0000 0000 - 0110 0100
mov ax,0ff64hneg al ;ax=ff9ch,OF=0、SF=1、ZF=0、PF=1、CF=1、AF=1sub al,9dh ;ax=ffffh,OF=0、SF=1、ZF=0、PF=1、CF=1、AF=1neg ax ;ax=0001h,OF=0、SF=0、ZF=0、PF=0、CF=1、AF=1dec al ;ax=0000h,OF=0、SF=0、ZF=1、PF=1、CF=1、AF=0neg ax ;ax=0000h,OF=0、SF=0、ZF=1、PF=1、CF=0、AF=0
比较指令CMP(compare)
CMP
指令将目的操作数减去源操作数,按照定义相应设置状态标志
CMP
指令执行的功能与SUB指令相同,但结果不回送目的操作数
CMP reg,imm/reg/mem ;reg-imm/reg/memCMP mem,imm/reg ;mem-imm/reg
执行比较指令之后,可以根据标志判断两个数是否相等、大小关系等
cmp al,100 ;al-100jb below ;al<100,跳转到below执行sub al,100 ;al≥100, al←al-100inc ah ;ah←ah+1below: ...
符号扩展指令
符号扩展是指用一个操作数的符号位(即最高位)形成另一个操作数,后一个操作数的各位是全0(正数)或全1(负数)。符号扩展不改变数据大小(符号扩展指高一半是符号位,没有实际的数值)
- 对于数据64H(表示数据100),其最高位D7为0,符号扩展后高8位都是0,成为0064H(仍表示数据100)
- 对于数据ff00H(表示有符号数-256),其最高位D15为1,符号扩展后高16位都是1,成为ffffff00H(仍表示有符号数-256)
符号扩展指令常用于获得倍长的数据
不影响标志位
CBW ;AL的符号扩展至AH byte to word;如AL的最高有效位是0,则AH=00;AL的最高有效位为1,则AH=FFH。AL不变CWD ;AX的符号扩展至DX word to double word;如AX的最高有效位是0,则DX=00;AX的最高有效位为1,则DX=FFFFH。AX不变
乘法指令
MUL r8/m8 ;无符号字节乘法;AX←AL×r8/m8MUL r16/m16 ;无符号字乘法;DX.AX←AX×r16/m16 高字节放入DX,低字节放入AXIMUL r8/m8 ;有符号字节乘法;AX←AL×r8/m8IMUL r16/m16 ;有符号字乘法;DX.AX←AX×r16/m16
乘法指令如下影响
OF
和
CF
标志:
-
MUL
指令——若乘积的高一半(
AH
或
DX
)为0,则
OF
=
CF
=0;否则
OF
=
CF
=1
-
IMUL
指令——若乘积的高一半是低一半的符号扩展,则
OF
=
CF
=0;否则均为1
乘法指令对其他状态标志没有定义
- 对标志没有定义:指令执行后这些标志是任意的、不可预测的
- 对标志没有影响:指令执行不改变标志状态
mov al,0b4h ;al=b4h=180mov bl,11h ;bl=11h=17mul bl ;ax=al*bl=Obf4h=3060;ax高8位不为0,所以OF=CF=1mov al,0b4h ;al=b4h=-76mov bl,11h ;bl=11h=17imul bl ;ax=faf4h=-1292; AX高8位含有效数字,所以OF=CF=1
除法指令
DIV r8/m8 ;无符号字节除法;AL←AX÷r8/m8的商,Ah←AX÷r8/m8的余数DIV r16/m16 ;无符号字除法;AX←DX.AX÷r16/m16的商,DX←DX.AX÷r16/m16的余数IDIV r8/m8 ;有符号字节除法:;AL←AX÷r8/m8的商,Ah←AX÷r8/m8的余数IDIV r16/m16 ;有符号字除法:;AX←DX.AX÷r16/m16的商,DX←DX.AX÷r16/m16的余数
注意:商和余数分开放
mov ax,0400h ;ax=400h=1024mov bl,b4h ;bl=b4h=180div bl ;商al=05h=5;余数ah=7ch=124mov ax,0400h ;ax=400h=1024mov bl,b4h ;bl=b4h=-76idiv bl ;商al=f3h=-13;余数ah=24h=36
BIOS中断服务
- 固化在系统内部的函数集合,通过这些中断服务和系统控制硬件资源
- 主板的BIOS负责初始硬件检测和系统引导
- VGA BIOS(如果有VGA卡的话)处理所有的屏幕处理函数
(INT 10
文字/绘图显示模块)
- 固定磁盘BIOS管理硬盘驱动器
(INT 13
软盘/硬盘/光驱读写形式)
DOS系统调用
DOS是位于低级BIOS之上的一个软件层,通过DOS系统调用提供进入低级BIOS的接口,DOS将调用相应的一种低级BIOS来完成所要求的任务
Dos操作系统为程序员提供的函数库,包括信息输入输出和文件操作等功能。比如利用9号功能调用,显示字符串
我们也可以抛开DOS调用,直接访问BIOS函数库
BIOS中断:字符属性
所谓属性是指字符的颜色、背景颜色、是否闪烁、有没有底线等性质。常用一个字节 ( 8 个位 ) 来表示文字颜色和背景颜色,通常以第 0~3 位表示文字本身颜色;第 4~6 位表示背景颜色;第 7 个位,表示是否闪烁,0 表示不闪烁,1 表示闪烁
颜色是用 4 个位表示时,可以表现出 16 种颜色,如下表:
二进制数 | 颜色 |
---|---|
0000 | 黑色 |
0001 | 蓝色 |
0010 | 绿色 |
0011 | 青色 |
0100 | 红色 |
0101 | 紫红色 |
0110 | 棕色 |
0111 | 银色 |
1000 | 灰色 |
1001 | 淡蓝色 |
1010 | 淡绿色 |
1000 | 淡青色 |
1100 | 淡红色 |
1101 | 淡紫红色 |
1110 | 黄色 |
1111 | 白色 |
BIOS中断:设定显示模式
- 调用号:
0
- 参数:
AL
AL
=00 40×25黑白方式
AL
=01 40×25彩色方式
AL
=02 80×25黑白方式
AL
=03 80×25彩色方式
…
调用方式:ah
设为调用号
0
,然后设置参数值
al
,最后用
int 10h
来进入BIOS中断
BIOS中断:置光标位置
- 调用号:
2
- 参数:
BH
= 页号 设为0即可
DH
= 行
DL
= 列
BIOS中断:在光标位置显示字符
- 调用号:
9
- 参数:
BH
= 显示页
AL
= 字符(ascii码)
BL
= 字符属性(颜色等)
CX
= 字符重复次数
BIOS中断:显示字符串
- 调用号:
13H
- 参数:
BP
= 串地址
CX
= 串长度
DH
,
DL
= 起始行列
BH
= 页号 设为0即可
AL
= 0,
BL
= 属性
.model tiny.code.startupmov bp, offset strmov bl, 04h ;红色,不闪烁mov cx, 12mov dx, 0815hmov ah, 13hint 10h.exit 0str db \'Hello World!\'end