怎样增加一个自定义的系统功能调用(内详)

hejunhard 2004-12-23 04:50:56
7、请编写一DOS程序,为INT21H增加AH=0FFH子功能,作用是将BL中的非压缩BCE码转换为ASCII码,以方便其他程序的使用。

其中的BCD码转换我自已会.
关键是这个DOS程序的结构是怎样的,
写好后要放在什么位置.
使使我们在汇编中用语句
mov ah 0ffh
int 21h
可以调用到这个子函数.
...全文
123 点赞 收藏 14
写回复
14 条回复
clumsy 2004年12月27日
;
; 需生成 .com 格式的程序. 如果使用的是 Masm5.0 的话, 通过 exe2bin 进行转换;
; 如果是 Masm6.x, ml /AT 或者在链接时 link /TINY
;
;DAT SEGMENT PARA 'DAT' ;*-
;ADDRESS DD ? ;*-
;DAT ENDS ;*-
CODE SEGMENT PARA 'CODE'
ASSUME DS:CODE,CS:CODE
org 100h ;*+
MAIN PROC FAR
START: ;PUSH DS ;*-
;XOR AX,AX ;*-
;PUSH AX ;*-
;MOV AX,DAT ;*-
;MOV DS,AX
MOV AL,21H
MOV AH,35H
INT 21H ;取原中断向量到ES:BX中
MOV WORD PTR ADDRESS,BX;保存此中断向量
MOV WORD PTR ADDRESS+2,ES
; PUSH DS ;*-
;MOV AX,CS ;*-
;MOV DS,AX ;*-
MOV DX, OFFSET DOS
MOV AL,21H
MOV AH,25H
INT 21H;设置新的中断向量
;POP DS ;*-
MOV BL,8
MOV AH,0FFH;调用自定义中断处理子函数
INT 21H
MOV DX,WORD PTR ADDRESS
MOV DS,WORD PTR ADDRESS+2
MOV AL,21H
MOV AH,25H
INT 21H ;恢复成原来的中断向量
; RET
MOV AH, 4CH
INT 21H
MAIN ENDP

ADDRESS DD ?

DOS PROC FAR

CMP AH,0FFH
JE CHANGE

JMP CS:ADDRESS ;跳到原中断向量处执行
CHANGE:ADD BL,30H;转成ASCII码

IRET
DOS ENDP

CODE ENDS
END START
回复 点赞
hejunhard 2004年12月26日
什么是驻留方式结束,为什么以这种方式就不会崩溃.
回复 点赞
clumsy 2004年12月26日
中断向量是 4 字节的远程入口, 你获取时只保存了 offset, 转移到原来的中断向量, 以及自己例程的返回的方法也就相应地错了. 自己的代码, 既然重置了中断向量, 要么在自己的程序结束前恢复原来的中断入口, 要么自己的程序以驻留方式结束, 而不能和普通程序似的简单地终止, 否则, 后面运行的程序很可能崩溃, 在你这里, 则肯定是会有问题的!
回复 点赞
hejunhard 2004年12月26日
感谢各位帮忙,我按大家意思写了如下程序,错在哪?
DAT SEGMENT PARA 'DAT'
ADDRESS DW ?
DAT ENDS
CODE SEGMENT PARA 'CODE'
ASSUME DS:DAT,CS:CODE
MAIN PROC FAR
START: PUSH DS
XOR AX,AX
PUSH AX
MOV AX,DAT
MOV DS,AX
MOV AL,21H
MOV AH,35H
INT 21H ;取原中断向量到BX中
MOV ADDRESS,BX;保存此中断向量
PUSH DS
MOV AX,0
MOV DS,AX
LEA DX,DOS
MOV AL,21H
MOV AH,25H
INT 21;设置新的中断向量
POP DS
MOV BL,8
MOV AH,0FFH;调用自定义中断处理子函数
INT 21H
RET
MAIN ENDP
DOS PROC FAR
CMP AH,0FFH
JE CHANGE
PUSH CS
JMP ADDRESS ;跳到原中断向量处执行
CHANGE:ADD BL,30H;转成ASCII码
RET
DOS ENDP

CODE ENDS
END START
回复 点赞
clumsy 2004年12月26日
JMP ADDRESS 这一句有问题. 最好是把 ADDRESS DD ? 放到 CODE 段里, 通过 CS 来寻址 (JMP CS:ADDRESS), 否则的话, 很难处理好 DS 的关系.
回复 点赞
hejunhard 2004年12月26日
有个问题
DAT SEGMENT PARA 'DAT'
ADDRESS DD ?
DAT ENDS
CODE SEGMENT PARA 'CODE'
ASSUME DS:DAT,CS:CODE
MAIN PROC FAR
START: PUSH DS
XOR AX,AX
PUSH AX
MOV AX,DAT
MOV DS,AX
MOV AL,21H
MOV AH,35H
INT 21H ;取原中断向量到ES:BX中
MOV WORD PTR ADDRESS,BX;保存此中断向量
MOV WORD PTR ADDRESS+2,ES
PUSH DS
MOV AX,CS
MOV DS,AX
MOV DX, OFFSET DOS
MOV AL,21H
MOV AH,25H
INT 21H;设置新的中断向量(执行到这里就自动退出了)
POP DS
MOV BL,8
MOV AH,0FFH;调用自定义中断处理子函数
INT 21H
MOV DX,WORD PTR ADDRESS
MOV DS,WORD PTR ADDRESS+2
MOV AL,21H
MOV AH,25H
INT 21H ;恢复成原来的中断向量
RET
MAIN ENDP
DOS PROC FAR

CMP AH,0FFH
JE CHANGE

JMP ADDRESS ;跳到原中断向量处执行
CHANGE:ADD BL,30H;转成ASCII码

IRET
DOS ENDP

CODE ENDS
END START
回复 点赞
clumsy 2004年12月26日
所谓的驻留方式, 就是程序结束之后, 仍然有一部分内容停留在内存里. 如果你的这个扩展的中断功能只是自己的这个程序里面使用的话, 不需要驻留方式, 只需要在程序结束前恢复原来的 int21h 中断入口就可以了. 如果是要求可以被其它的程序来使用的话, 就必须采用驻留方式了.
由于你的这个代码和数据结构都比较简单, 也是为了计算驻留长度的方便起见, 最后是尽可能地将程序写成 .com 类型的. 具体的驻留方法可以参考 int21h(AH=31h) 的功能调用说明.

另外, 你的自己的这个中断代码有些问题: 一是不要在这里恢复原来的中断向量, 结构上不太好, 确实要这么做的话, 也可以, 但是, 应该 '保存-恢复' 使用到的寄存器, 尤其是如果以驻留方式供其它程序使用时, 否则, 破坏了原调用的寄存器的内容, 会出问题的. 其次, CHANGE: 之后的返回应该用 iret
回复 点赞
hejunhard 2004年12月26日
刚改的,还是无法实现啊

DAT SEGMENT PARA 'DAT'
ADDRESS DD ?
DAT ENDS
CODE SEGMENT PARA 'CODE'
ASSUME DS:DAT,CS:CODE
MAIN PROC FAR
START: PUSH DS
XOR AX,AX
PUSH AX
MOV AX,DAT
MOV DS,AX
MOV AL,21H
MOV AH,35H
INT 21H ;取原中断向量到ES:BX中
MOV WORD PTR ADDRESS,BX;保存此中断向量
MOV WORD PTR ADDRESS+2,ES
PUSH DS
MOV AX,CS
MOV DS,AX
MOV DX, OFFSET DOS
MOV AL,21H
MOV AH,25H
INT 21;设置新的中断向量
POP DS
MOV BL,8
MOV AH,0FFH;调用自定义中断处理子函数
INT 21H
RET
MAIN ENDP
DOS PROC FAR
MOV DX,WORD PTR ADDRESS
MOV DS,WORD PTR ADDRESS+2
MOV AL,21H
MOV AH,25H
INT 21 ;恢复成原来的中断向量
CMP AH,0FFH
JE CHANGE

JMP ADDRESS ;跳到原中断向量处执行
CHANGE:ADD BL,30H;转成ASCII码

RET
DOS ENDP

CODE ENDS
END START
回复 点赞
jk88811 2004年12月25日
难道楼主的意思不是这样吗?

mov ah 0ffh
int 21h
可以调用到这个子函数.

这是楼主要的效果呀
回复 点赞
kokblack 2004年12月25日
不太同意 jk88811(文哥)的说法,他好像是要自己定义一个21h的一个功能号吧。
回复 点赞
awcx 2004年12月25日
高手
回复 点赞
jk88811 2004年12月24日
用INT 21H 里的25H和35H 功能保存原中断向量和修改成你的中断处理程序入口地址,然后就可以调用中断啦!

具体找课本吧
回复 点赞
kokblack 2004年12月23日
这个方法和自己写中断向量表的方法差不多。就是不知具体用什么指令!
回复 点赞
cnvb 2004年12月23日
1.保存INT21中断的原程序调用地址
2.用自己所写的程序地址替换原INT21程序地址
3.当INT21被调用时检测AH是不是OFFH如果是的话就调用那个转换程序,不是的话转INT21原地址继续运行.
这只是偶个人意见,不是之处还请大虾们指教!!!
回复 点赞
发动态
发帖子
汇编语言
创建于2007-08-27

1.9w+

社区成员

4.1w+

社区内容

汇编语言(Assembly Language)是任何一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,亦称为符号语言。
社区公告
暂无公告