作为汇编语言的课程笔记,方便之后的复习与查阅
本篇为课程第六次课内容
目录
- 算术运算指令
- 加法指令ADD
- 带进位加法指令ADC
- 增量指令INC(increment)
- 减法指令SUB(subtract)
- 带借位减法指令SBB
- 减量指令DEC(decrement)
- 求补指令NEG(negative)
- 比较指令CMP(compare)
- 符号扩展指令
- 乘法指令
- 除法指令
- BIOS中断服务
- 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/mem
ADD 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+CF
ADC 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 bx
inc byte ptr [bx]
减法指令SUB(subtract)
SUB
指令将目的操作数减去源操作数,结果送到目的操作数
SUB reg,imm/reg/mem ;reg←reg-imm/reg/mem
SUB 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-CF
SBB mem,imm/reg ;mem←mem-imm/reg-CF
减量指令DEC(decrement)
DEC
指令对操作数减1(减量),主要用于对计数器和地址指针的调整
DEC
指令不影响进位CF
标志,按定义设置其他状态标志
DEC reg/mem ;reg/mem←reg/mem-1
dec bx
dec 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,0ff64h
neg al ;ax=ff9ch,OF=0、SF=1、ZF=0、PF=1、CF=1、AF=1
sub al,9dh ;ax=ffffh,OF=0、SF=1、ZF=0、PF=1、CF=1、AF=1
neg ax ;ax=0001h,OF=0、SF=0、ZF=0、PF=0、CF=1、AF=1
dec al ;ax=0000h,OF=0、SF=0、ZF=1、PF=1、CF=1、AF=0
neg 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/mem
CMP mem,imm/reg ;mem-imm/reg
执行比较指令之后,可以根据标志判断两个数是否相等、大小关系等
cmp al,100 ;al-100
jb below ;al<100,跳转到below执行
sub al,100 ;al≥100, al←al-100
inc ah ;ah←ah+1
below: ...
符号扩展指令
符号扩展是指用一个操作数的符号位(即最高位)形成另一个操作数,后一个操作数的各位是全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/m8
MUL r16/m16 ;无符号字乘法
;DX.AX←AX×r16/m16 高字节放入DX,低字节放入AX
IMUL r8/m8 ;有符号字节乘法
;AX←AL×r8/m8
IMUL 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=180
mov bl,11h ;bl=11h=17
mul bl ;ax=al*bl=Obf4h=3060
;ax高8位不为0,所以OF=CF=1
mov al,0b4h ;al=b4h=-76
mov bl,11h ;bl=11h=17
imul 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=1024
mov bl,b4h ;bl=b4h=180
div bl ;商al=05h=5
;余数ah=7ch=124
mov ax,0400h ;ax=400h=1024
mov bl,b4h ;bl=b4h=-76
idiv 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
.startup
mov bp, offset str
mov bl, 04h ;红色,不闪烁
mov cx, 12
mov dx, 0815h
mov ah, 13h
int 10h
.exit 0
str db 'Hello World!'
end