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

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

其中的BCD码转换我自已会.
关键是这个DOS程序的结构是怎样的,
写好后要放在什么位置.
使使我们在汇编中用语句
mov ah 0ffh
int 21h
可以调用到这个子函数.
...全文
243 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
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原地址继续运行.
这只是偶个人意见,不是之处还请大虾们指教!!!

21,499

社区成员

发帖
与我相关
我的任务
社区描述
汇编语言(Assembly Language)是任何一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,亦称为符号语言。
社区管理员
  • 汇编语言
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧