文章目录
前言
学习教材为 王爽老师的《汇编语言》(第四版),作业题目是我们老师出的非书中原题,由于作者自己学识浅薄,文章内容仅供参考,如有错漏欢迎批评指正。
一、题目
编写安装7ch的中断例程
功能:求数据段前16个字节型数据的和
参数:ds:si指向数据段起始位置
返回值:和存放在ax中
应用举例(测试应用程序):
assume cs:code, ds:data
data segment
db 1,23,4,5,6,7,87,8,78,7,98,123,123,56,22,222,25,225,100,134
data ends
code segment
start:
mov ax,data
mov ds, ax
mov si, 0
int 7ch
mov bx, ax
mov ax, 4c00h
int 21h
code ends
end start
二、汇编代码
assume cs:code
code segment
start:
;中断安装
mov ax,cs
mov ds,ax
mov si,offset sumer ;使用 SI 指向中断处理程序 sumer 的偏移地址
mov ax,0
mov es,ax
mov di, 200h ;将 DI 设置为 200h,目标位置在中断向量表后面
mov cx,offset sumerend - offset sumer ;计算中断处理程序 sumer 的长度,设置 CX 为长度值
cld ;清除方向标志,确保字符串操作从低地址到高地址移动
rep movsb ;使用 REP MOVSB 指令将 sumer 复制到中断向量表后的内存位置。
;设置中断程序
mov ax,0
mov es,ax ;将 ES 设置为 0,指向中断向量表
mov word ptr es:[7ch*4],200h ;设置中断向量表中 int 7Ch 的向量,地址为 0000:0200h
mov word ptr es:[7ch*4+2],0
mov ax,4c00h
int 21h
;求和函数
sumer:
mov cx,16
xor ax,ax ;将 ax 清零
xor bx,bx ; bx 清零
s:
add al,ds:[bx] ;求和
adc ah,0 ;将高位存储在 ah 中
inc bx
loop s ;循环至 cx 为 0
iret
sumerend:
nop
code ends
end start
代码解析
注:1、2 部分几乎所有7ch中断程序可套用
1.中断安装部分
mov ax,cs
mov ds,ax
mov si,offset sumer
- 将代码段寄存器
CS
的值加载到AX
,然后将其移动到DS
,以便数据段寄存器指向代码段。 - 使用
SI
指向中断处理程序sumer
的偏移地址。
mov ax,0
mov es,ax
mov di, 200h
- 将
ES
设置为0,指向中断向量表。 - 将
DI
设置为200h
,目标位置在中断向量表后面。
mov cx,offset sumerend - offset sumer
cld
rep movsb
- 计算中断处理程序
sumer
的长度,设置CX
为长度值。 - 清除方向标志(
CLD
),确保字符串操作从低地址到高地址移动。 - 使用
REP MOVSB
指令将sumer
复制到中断向量表后的内存位置。
2.设置中断向量
mov ax,0
mov es,ax
mov word ptr es:[7ch*4],200h
mov word ptr es:[7ch*4+2],0
- 将
ES
设置为0,指向中断向量表。 - 设置中断向量表中
int 7Ch
的向量,地址为0000:0200h
。
3.程序结束
mov ax,4c00h
int 21h
- 使用 DOS 中断
int 21h
以退出程序。
4.中断处理程序 ‘sumer’
sumer:
mov cx,16
xor ax,ax
xor bx,bx
s:
add al,ds:[bx]
adc ah,0
inc bx
loop s
iret
sumerend:
nop
sumer
是中断处理程序,负责求和数据段前16个字节的数据。- 初始化
CX
为16,用于循环计数。 - 清零
AX
和BX
寄存器。 - 循环16次,逐字节相加:
- 将数据段中
BX
指向的字节值加到AL
。 - 使用
ADC
指令将进位加到AH
。 - 增加
BX
。 - 循环直到
CX
变为0。
- 将数据段中
- 使用
IRET
返回主程序。
三、在DOSBox中用debug调试结果
安装中断程序(zd.asm
)后,debug
测试程序(test.exe
)就可以看到ax的值已经为前16个数求和后的值,经检验结果无误