作为汇编语言的课程笔记,方便之后的复习与查阅

本篇为课程第六次课内容


目录

  • 算术运算指令
  • 加法指令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 ---- 重点理解对CFOF的影响

汇编BIOS调用读取文件 汇编bios中断_数据


汇编BIOS调用读取文件 汇编bios中断_数据_02


注意:上面的数都是用补码表示的

带进位加法指令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

汇编BIOS调用读取文件 汇编bios中断_操作数_03


用汇编处理时最多只能处理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 ---- 重点理解对CFOF的影响

汇编BIOS调用读取文件 汇编bios中断_汇编BIOS调用读取文件_04


汇编BIOS调用读取文件 汇编bios中断_寄存器_05

带借位减法指令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

汇编BIOS调用读取文件 汇编bios中断_数据_06

减量指令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

乘法指令如下影响OFCF标志:

  • MUL指令——若乘积的高一半(AHDX)为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
  • 参数:ALAL=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 = 串长度
    DHDL = 起始行列
    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

汇编BIOS调用读取文件 汇编bios中断_汇编BIOS调用读取文件_07