- 浏览: 2060575 次
- 性别:
- 来自: 厦门
文章分类
- 全部博客 (1409)
- asp/asp.net学习 (241)
- oracle (10)
- delphi (295)
- java (27)
- pb (1)
- 每日点滴 (49)
- 学习方法 (40)
- 思想方面 (104)
- C语言 (5)
- C++ (1)
- 代码重构经验 (5)
- 软件工程 (3)
- 数据库 (99)
- 英语学习 (3)
- mysql (1)
- 该关注的网站或者网页 (42)
- 总结 (7)
- 要去做的事情 (33)
- 算法 (1)
- 网络方面 (29)
- 随感 (96)
- 操作系统 (36)
- UML (12)
- 常用工具的使用 (55)
- 脚本 (7)
- 汇编 (62)
- 数据结构 (2)
- 财务 (38)
- 语文作文 (16)
- 法律 (1)
- 股票 (88)
最新评论
-
devwang_com:
可以,学习了~~
列出文件夹下所有文件夹的树形结构--Dos命令 tree的使用 -
hvang1988:
不管用啊 frxrprt1.PreviewForm.Pare ...
fastReport预览时嵌入到别的窗体 -
00915132:
我也有这个疑问,非常 感 谢
left join加上where条件的困惑 --SQL优化 -
zhuyoulong:
学习了,高效读书
软件架构师要读的书 -
nTalgar:
非常感谢分享!
Application.ProcessMessages用法:
转自:http://www.x86asm.com/DisplayArticle.asp?BoardID=5&ArticleID=14
五 键盘输入扩充程序
有了前一节的基本驻留程序为基础,就可以建立起不同的应用程序.接下来,就写一个驻留程序,把用户敲入的字符,用一系列的字符来取代.这样可以减少用户的击键次数.
首先,先复习一下前一节的驻留程序的格式,如下所示:
cseg segment
assume cs:cseg,ds:cseg
org 100h
start:
jmp Initialize
Old_Keyboard_IO dd ?
;Section 1
new_keyboard_io proc far
sti
;Section 2
pushf
assume ds:nothing
call Old_Keyboard_IO
nop
iret
new_keyboard_io endp
;Section 3
Initialize:
assume cs:cseg,ds:cseg
mov bx,cs
mov ds,bx
mov al,16h
mov ah,35h
int 21h
mov word ptr Old_Keyboard_IO,bx
mov word ptr Old_Keyboard_IO[2],es
;End Section 3
mov dx,offset new_keyboard_io
mov al,16h
mov ah,25h
int 21h
mov dx,offset Initialize
int 27h
cseg ends
end start
只要New_keyboard_IO这个程序,就可以把以上的程序变成许多不同的键盘应用程序.在开始设计之前,必须解决一些问题.
首先,必须决定哪些键可以用来加以扩充.如果把一般的英文字母或是数目字做为扩充字符的话可能会出现一些问题.如果是对控制字符做扩充,应该不会有什么问题,但是DOS把某些控制字符视为特殊的功能.譬如Control_H,IBM PC本身有一组自己独有和增加字符(extended character),譬如:功能键(F1到F10),以及ALT键和其它组合所产生的字符等.这些增加字符通常都是使用在文书编辑程序中,这些字符比较适合用来作为扩充字符用.这组字符是由两个码组成,前面一个码永远是0,因此DOS可以很容易加以分辨.而且使用这些字符作为扩充字符对DOS的使用也不会产生太大的影响.下面是扩充字符组的第二个码大小:
1 2 Paoudo_NULL 3 4 5
6 7 8 9 10
11 12 13 14 15 Shift_Tab 16 Alt_Q 17 Alt_W 18 Alt_E 19 Alt_R 20 Alt_T 21 Alt_Y 22 Alt_U 23 Alt_I 24 Alt_O 25 Alt_P 26 27 28 29 30 Alt_A
31 Alt_S 32 Alt_D 33 Alt_F 34 Alt_G 35 Alt_H
36 Alt_J 37 Alt_K 38 Alt_L 39 40
41 42 43 44 Alt_Z 45 Alt_X
46 Alt_C 47 Alt_V 48 49 50
51 52 53 54 55
56 57 58 59 F1 60 F2
61 F3 62 F4 63 F5 64 F6 65 F7
66 F8 67 F9 68 F10 69 70
71 HOME 72 UpArrow 73 PgUp 74 75 LeftArrow
76 77 RightArrow 78 79 End 80 DownArrow
81 PgDn 82 Insert 83 Delete 84 Shift_F1 85 Shift_F2
86 Shift_F3 87 Shift_F4 88 Shift_F5 89 Shift_F6 90 Shift_F7
91 Shift_F8 92 Shift_F9 93 Shift_F10 94 Control_F1 95 Control_F2
96 Control_F3 97 Control_F4 98 Control_F5 99 Control_F6 100 Control_F7
101 Control_F8 102 Control_F9 103 Control_F10 104 Alt_F1 105 Alt_F2
106 Alt_F3 107 Alt_F4 108 Alt_F5 109 Alt_F6 110 Alt_F7
111 Alt_F8 112 Alt_F9 113 Alt_F10 114 Control_PrtSc 115 Control_LArrow
116 Control_RArrow 117 Control_End 118 Control_PgDn 119 Control_Home 120 Alt_1
121 Alt_2 122 Alt_3 123 Alt_4 124 Alt_5 125 Alt_6
126 Alt_7 127 Alt_8 128 Alt_9 129 Alt_0 130 Alt_Hyphan
131 Alt_Space 132 Control_PgUp
接下来,需要决定把扩充字符扩充成什么样的字符串.譬如,所扩充的字符串以什么作结尾?有一个可能的选择是:回车键(Carriage Return,ASCII码0DH).这种选择很合乎逻辑,因为一般的指令都能是以回车键做结尾.但是,如果选择回车键名做扩充字符串的结尾,那么就很难表示许多行的扩充字符串.另外一个选择是使用$作为扩充字符串的结尾.但是,因为有些DOS的系统调用使用$作为字符结尾;因此如果采用$时,那么扩充字符串中就不能有$出现.
C语言中都是采用ASCII码的0做为字符串的结尾,这种形式的字符串称为ASCII字符串(ASCII零结尾).使用ASCII字符串格式,就可以表示所有的可见字符和不可见字符,因为从键盘不可能输入ASCII码为0的字符.
下面的例子中,把F1这个键(扩充码59)定义为DIR指令.也可以把F1定义成以下的指令:
MASM MACRO;
LINK MACRO;
EXE2BIN MACRO.EXE MACRO.COM;
上面的指令中,每一行都是以回车键作结尾的.
最后要做的是,解决将扩充的字符返回给DOS的问题.通常每当在键盘敲入一个键时,DOS就会从键盘输入队列取得一个字符.因此必须设法欺骗DOS,让它接受一连串的字符.
DOS借检查键盘的状态来判断,是否有字符输入,ROM BIOS上的键盘输入功能在没有输入字符时就把ZF(Zero Flag)设定为1,否则就把ZF设定为0.如果可以控制这个功能,反复地欺骗DOS目前有字符要输入,然后把预的字符串传回给DOS,那么就可以让DOS接受任何数量的字符.
5.1 基本的扩充程序
可以把上面的空的New_Keyboard_IO程序,改用以下的程序来代替.
New_Keyboard_IO proc far
sti
cmp ah,0 ;A read request?
je ksread
cmp ah,1 ;A status request?
je ksstat
assume ds:nothing ;Let original routine
jmp Old_Keyboard_IO ;Do remaining subfunction
ksRead:
call keyRead ;Get next char to return
iret
ksstat:
call keyStat ;GetStatus
ret 2 ;It's important!!
New_Keyboard_IO endp
上面的New_Keyboard_IO程序中,把0H(读取字符)和1H(取得键盘状态)这两项功能自行处理.这个程序很简单,但是其中有一个关键点.当我们处理取得键盘状态的功能时,因为原先的键盘中断处理程序是利用ZF返回键盘状态,因此程序包中也必须保有这种特性,如果使用IRET返回的话,那么设定好ZF就会因为CPU状态标志从堆栈中取出,而恢复成未中断前的状态.
为了解决这个问题可以使用RET的参数来设置.这个参数是用来指示从堆栈中取出多少个字节.通常这是用在高级语言的子程序返回时,用来从堆栈中除去一些参数或是变数.在这里我们希望用来移去原先中断时堆栈的CPU状态,这样才有办法把改变的ZF传回,因此在这里使用了RET 2这个指令.
上面的程序码中调用到Keyread和KeyStat这两个子程序,其内容如下所示:
assume ds:nothing
;If expansion is in progress,return a fake status
;of ZF=0,indicatin gthat a character is ready to be
;read,If expansion is not in progress,then return
;the actual status from the keyboard
KeyStat proc
cmp cs:current,0
jne FakeStat
pushf ;Let original routine
call Old_Keyboard_IO ;get keyboard status
ret
FakeStat:
mov bx,1 ;Fake a "char ready"
cmp bx,0 ;by clearing ZF
KeyStat endp
;Read a character from the keyboard input queue,
;if not expanding or the expansion string.
;if expansion is in progress
KeyRead proc
cmp cs:current,0
jne ExpandChar
ReadChar:
mov cs:current,0 ;Slightly peculiar
pushf ;Let original routine
call Old_Keyboard_IO ;Get keyboard status
cmp al,0
je Extended
ReadDone:
ret
Expanded:
cmp ah,59 ;Is this character to expand?
jne ReadDone ;If not,then return it normally
;If so,then start expanding
mov cs:current,offset string
ExpandChar:
push si
mov si,cs:current
mov al,cs:[si]
inc cs:current
pop si
cmp al,0 ;Is this end of string?
je ReadChar ;If so,then read a real char?
ret
KeyRead endp
;Pointer to where we are in the expansion string
current dw 0
;String we will return when an F1 is typed
;0DH is ASCII carriage return
string db 'DIR',0dh,0
上面的程序中,使用了一个指针current,这个指针指向传给DOS的下一个字符.如果current等于0时,就表示扩充字符没了.如果current不等于0,那么current所指的字符就会被传回,除非所指到的字符是ASCII 0,如果current所指到的字符是ASCII 0,那么就必须把current设定成0.
状态检查程序KeyStat和字符输入程序KeyRead都各有两个部分,一部分是当current等于0,另一部分则是当current等于0.
如果current等于0,也就是没有扩充字符时,那么状态检查程序就需调用旧的键盘输入程序,来检查目前键盘输入队列的状态.如果current不等于0,ZF就必须设定成0,以表示目前有字符输入.ZF要设定成0或1,可以先执行某一运算让结果为0或非0即可.
键盘输入程序是整个程序最复杂的部分.这个程序决定了下个送给DOS的字符是什么.如果扩充字符送完时,就调用旧的键盘输入程序取得下一个输入的字符.无论从键盘输入的字符是什么,都必须检查是否是希望扩充的字符.键盘输入程序是把输入的结果放在寄存器AL中.如果输入的字符是增加字符时(如F1),那么AL的内容是0,增加的字符码则放在AH中.
如果读到的字符是希望扩充的字符F1,那么就必须开始进行扩充工作.这时候就必须把指针current指到扩充字符串的开头.大多数人常犯的一个错误是:使用mov cs:current,string而不是mov cs:current,offset string.这两者的差别在于前者是错误的,因为它的意思是把一个字节的内容移到一个字节之中,汇编器会强迫两者的形式吻合.后者则是正确的,因为 我们希望做的是把式string指向的地址值移到current之中.
当我们在进行扩充时,就把指针current所指的字节内容移到AL中,只要AL的内容不是0,就不必管AH的内容是什么.如果AL是0的话,就表示已经到了扩充字符的结尾了.这表示不应该传回0,而必须重新调用Old_Keyboard_IO ,以便从键盘取得输入字符.
在程序包KeyRead中有一行指令比较特殊,你也许注意到了,在进入KeyRead,当确定current为0时,接下来又把current设定成0.这样做虽然有些奇怪,却没有任何伤害;但是对于扩充字符串到达结尾时,却很有用.当我们到达扩充字符串的结尾时,current的内容将指到字符串结尾的下一个位置,而不是0.因此必把current设定为0,可以先跳到某一位置把current设定为0,然后再跳到ReadChar.而采取前面程序的做法时,只是浪费一行毫无伤害的指令,却可以使程序变得简明.
在这个程序中,每次使用到内存的内容时,都必须牵涉到段值,这一点相当重要.当计算机的控制权转移到我们的程序中时,我们对于DS的内容是不知道的.但是有两件事可以确定:第一,DS的内容对我们的程序几乎没有任何用;第二,DS的内容对于被中断的程序可能很重要.因此我们必须保证每次使用到内存位置时,都是使用目前的段,亦即以目前的CS值为标准.必须要确定:如果使用到任何寄存器的话那么在程序结束前,必须恢复其值.
5.2 多键扩充程序
上面的程序是把某一个特殊键扩充成一个字符串.如果要把一组特殊键扩充成其个别的扩充字符串,该如何做呢?
一个比较常见的做法是,修改上面的程序,让它接受被扩充字符以被扩充字符串为参数.譬如,如果这个程序名为MACRO,那么可以在AUTOEXEC.BAT中定义以下的指令:
........
MACRO F1 DIR
MACRO F2 DIR/W
MACRO F3 DIR *.ASM
MACRO F4 DIR *.COM
MACRO F5 DIR *.EXE
........
这种做法是把MACRO这程序一个个留在内存中,至于每一个所做的扩充字符串则分别定义在AUTOEXEC.BAT中,因此可以AUTOEXEC.BAT以的内容.来改变扩充字符的意思.每当执行AUTOEXEC.BAT的MACRO时,就把一个新的键盘程序和BIOS中的键盘处理程序连结起来.第二次执行MACRO则是在新的键盘处理程序上加上第二层的键盘处理程序,以后依次类推.每一个输入字符都必须经过一层一层的键盘处理程序,以过滤出被扩充字符.
这种键盘程序一层一层加上去的做法只能使用在希望被扩充字符不多时,因为 每一个希望被扩充字符需要将近一百个字节的驻留程序代码,如果要为128个功能键产生个别的扩充字符时,那么就要耗费13K字节的内存,显然可以采纳别的比较节省内存的方法.
如果可以在一个小程序中辨认出一个字符,那么也应该可以辨认出一个以上的字符.然后使用所辨认出的字符转换成索引值.再从一个由字符串所组成的表格中,找出所扩充的字符串.
一个字符串本身占用一个字节,而指到字符串的指针则占用两个字节,如果有128个字符需要扩充时,则总共需要284个字节.另外原先的程序大约需要增加50个字节.因此整个程序的大小就变成大约半K字节.假设每一个扩充字符串占用20个字节,那么128个扩充键就需2.5K字节,这和程序代码的0.5K字节加起来,总共也不过3K字节,还比前一种方法少10K字节.
上面的单键扩充程序转换成多键扩充程序时,只要修改其中的KeyRead这个程序以及数据区的内容即可.以下就是修改后的内容:
;Read a character from the keyboard input queue,
;if not expanding or the expansion string.
;if expansion is in progress
KeyRead proc
cmp cs:current,0
jne ExpandChar
ReadChar:
mov cs:current,0 ;Slightly peculiar
pushf ;Let original routine
call Old_Keyboard_IO ;Get keyboard status
cmp al,0
je Extended
jmp ReadDone
Extended:
cmp byte ptr cs:[si],0 ;Is this end of table?
je ReadDone
cmp ah,cs:[si]
je StartExpand
add si,3
jmp NextExt
StartExtend:
push bx
add si,1
mov bx,cs:[si]
mov cs:current,bx ;If so,start expanding
ExpandChar:
mov si,cs:current
mov al,cs:[si]
inc cs:current
cmp al,0 ;Is this end of string?
je ReadChar ;If so,then read a real char?
ReadDone:
pop si
ret
KeyRead endp
current dw 0
KeyTab db 59
dw dir_cmd
db 60
dw dir_wide
db 61
dw dir_asm
db 62
dw dir_com
db 63
dw dir_exe
db 50
dw make_macro
db 0 ;This must be last in key table
dir_cmp db 'DIR',0dh,0
dir_wide db 'DIR/W',0dh,0
dir_asm db 'DIR *.ASM',0dh,0
dir_com db 'DIR *.COM',0dh,0
dir_exe db 'DIR *.EXE',0dh,0
make_macro db 'MASM MACRO;',0dh,0
db 'LINK MACRO;',0dh,0
db 'EXE2BIN MACRO.EXE MACRO.COM',0dh,0
上面的程序是节省了一点的时间,但是对于和用户界面而言则变得比较不方便,因为把功能键的定义移到汇编语言的程序中.但是可以高法改写这个程序,让它在初次执行时从一个文件装载所定义的字符患上 .这样做并不会改变驻留程序代码的大小,因为装载文件的起始码可以在执行完后抛弃,因此不必占用驻留程序代码的位置.
5.3 单键扩充程序
以下是单键扩充成命令字符串的程序内容:
cseg segment
assume cs:cseg,ds:cseg
org 100h
Start:
jmp Initialize
Old_Keyboard_IO dd ?
assume ds:nothing
New_Keyboard_IO proc far
sti
cmp ah,0 ;Is this call a read request?
je ksRead
cmp ah,1 ;Is it a status request?
je ksStat ;Let original routine
jmp Old_Keyboard_IO ;handle remianing subfunction
ksRead:
call KeyRead ;Get next character to return
iret
ksStat:
call KeyStat ;Return appropriate status
ret 2 ;Important!!!
New_Keyboard_IO endp
KeyRead Proc near
cmp cs:current,0
jne ExpandChar
ReadChar:
mov cs:current,0 ;Slightly peculiar
pushf ;Let original routine
call Old_Keyboard_IO ;Determine keyboard status
cmp al,0
je Extended
ReadDone:
ret
Extended:
cmp ah,59 ;Is this character to expand?
jne ReadDone ;If not,return it normally
;If so,start expanding
mov cs:current,offset String
ExpandChar:
push si
mov si,cs:current
mov si,cs:[si]
inc cs:current
pop si
cmp al,0 ;Is this end of string?
je ReadChar ;If so,then read a real char?
ret
KeyRead endp
KeyStat proc near
cmp cs:current,0
jne FakeStat
pushf ;Let original routine
call Old_Keyboard_IO ;Determine keyboard
ret
FakeStat:
mov bx,1 ;Fake a "Character ready" by clearing ZF
cmp bx,0
ret
KeyStat endp
current dw 0
string db 'masm macro;',0dh
db 'link macro;',0dh
db 'exe2bin macro.exe macro.com',0dh,0
Initialize:
assume cs:cseg,ds:cseg
mov bx,cs
mov ds,bx
mov al,16h
mov ah,35h
int 21h
mov word ptr Old_Keyboard_IO,bx
mov word ptr Old_Keyboard_IO,es
mov dx,offset New_Keyboard_IO
mov al,16h
mov ah,25h
int 21h
mov dx,offset Initialize
int 27h
cseg ends
end Start
5.4 一般的键盘扩充程序Mactab.asm
以下和程序可以把由表的查询,将任意娄的扩充键扩充成命令字符串:
cseg segment
assume cs:cseg,ds:cseg
org 100h
Start:
jmp Initialize
Old_Keyboard_IO dd ?
assume ds:nothing
cmp byte ptr cs:[si],0 ;end of table
je ReadDone
cmp ah,cs:[si]
je StartExpand
add si,3
jmp NextExt
StartExpand:
add si,1
push bx
mov bx,cs:[si]
mov cs:current,bx
pop bx
ExpandChar:
mov si,cs:current
mov al,cs:[si]
inc cs:current
cmp al,0 ;end of string 2
je ReadChar ;then read real char
ReadDone:
pop si
ret 3
KeyRead endp
current dw 0
KeyTab db 59
dw dir_cmd
db 60
dw dir_wide
db 61
dw dir_asm
db 62
dw dir_com
db 63
dw dir_exe
db 50
dw make_macro
db 0 ;This must be last in key table
dir_cmp db 'DIR',0dh,0
dir_wide db 'DIR/W',0dh,0
dir_asm db 'DIR *.ASM',0dh,0
dir_com db 'DIR *.COM',0dh,0
dir_exe db 'DIR *.EXE',0dh,0
make_macro db 'MASM MACRO;',0dh,0
db 'LINK MACRO;',0dh,0
db 'EXE2BIN MACRO.EXE MACRO.COM',0dh,0
New_Keyboard_IO proc far
sti
cmp ah,0 ;Is this call a read request?
je ksRead
cmp ah,1 ;Is it a status request?
je ksStat ;Let original routine
jmp Old_Keyboard_IO ;handle remianing subfunction
ksRead:
call KeyRead ;Get next character to return
iret
ksStat:
call KeyStat ;Return appropriate status
ret 2 ;Important!!!
New_Keyboard_IO endp
KeyStat proc near
cmp cs:current,0
jne FakeStat
pushf ;Let original routine
call Old_Keyboard_IO ;Determine keyboard
ret
FakeStat:
mov bx,1 ;Fake a "Character ready" by clearing ZF
cmp bx,0
ret
KeyStat endp
;Read a character from the keyboard input queue,
;if not expanding or the expansion string.
;if expansion is in progress
KeyRead proc
cmp cs:current,0
jne ExpandChar
ReadChar:
mov cs:current,0 ;Slightly peculiar
pushf ;Let original routine
call Old_Keyboard_IO ;Get keyboard status
cmp al,0
je Extended
ReadDone:
ret
Expanded:
cmp ah,59 ;Is this character to expand?
jne ReadDone ;If not,then return it normally
;If so,then start expanding
mov cs:current,offset string
ExpandChar:
push si
mov si,cs:current
mov al,cs:[si]
inc cs:current
pop si
cmp al,0 ;Is this end of string?
je ReadChar ;If so,then read a real char?
ret
KeyRead endp
Initialize:
assume cs:cseg,ds:cseg
mov bx,cs
mov ds,bx
mov al,16h
mov ah,35h
int 21h
mov word ptr Old_Keyboard_IO,bx
mov word ptr Old_Keyboard_IO,es
mov dx,offset New_Keyboard_IO
mov al,16h
mov ah,25h
int 21h
mov dx,offset Initialize
int 27h
cseg ends
end Start
未完待续......
发表评论
-
用汇编写的病毒代码
2010-05-29 08:04 1899转自:http://www.programfan.com ... -
堆和栈(堆栈)的区别
2010-05-20 16:47 866转自:http://www.360doc.com/sho ... -
OllyDBG 入门系列(三)-函数参考
2010-05-06 14:07 1390转自:http://bbs.pediy.com/s ... -
OllyDBG 入门系列(二)-字串参考
2010-05-05 19:02 1142转自:http://bbs.pediy.com/s ... -
用汇编编写DOS下的内存驻留程序(4)
2010-05-05 11:04 1170转自:http://www.x86asm.com/Displa ... -
用汇编编写DOS下的内存驻留程序(3)
2010-05-05 11:03 896转自:http://www.x86asm. ... -
用汇编编写DOS下的内存驻留程序(2)
2010-05-05 11:02 767转自:http://www.x86asm. ... -
用汇编编写DOS下的内存驻留程序(1)
2010-05-05 11:01 1503转自:http://www.x86 ... -
补码 左移与右移 32位系统
2010-05-02 11:04 2796QQ:797801 计算机中 ... -
c语言控制语句对应的汇编语句代码
2010-04-29 18:15 2253转:http://blog.csdn.net/ ... -
调试windows程序
2010-03-21 10:11 814debug 只能支持1M的寻址 如果需要调 ... -
ds:[bp+2]
2009-11-28 13:22 907mov ax,0 mov ds ... -
程序的起始地址的段地址
2009-11-26 09:38 1325生成EXE之后用Debug加载后,查看寄存器内容如下: ... -
将内存FFFF:0--FFFF:b单元中的数据复制到0:200--0:20b单元中
2009-10-25 21:13 1677该程序的功能: 将内存FFFF:0--FF ... -
标志寄存器
2009-10-25 18:46 999方便记忆 OF 溢出(是/否) ... -
安全的一段内存空间 0:2000~0:02FF
2009-10-25 18:20 950看到120页了 我们要向内存里写东西 ... -
显示红心的汇编代码
2009-10-25 18:05 923assume cs:code code segment ... -
debug时 遇到loop 指令
2009-10-25 17:35 901debug时 遇到loop 指令 用 p指 ... -
Loop的使用
2009-10-23 21:06 1216看到107页了 王爽汇编第五章 Loop的使用 ... -
王爽汇编的第四章的一个小例子--待验证
2009-10-20 21:02 1171第四章的一些总结: 1. DOS系统是单任 ...
相关推荐
### 汇编语言下DOS内存驻留程序设计概览 #### 1. 内存驻留程序(TSR)概念解析 内存驻留程序,全称“Terminate and Stay Resident Program”(TSR),是一种在计算机系统中加载至内存、执行完毕后并不释放其占用的内存...
文件"用汇编编写DOS下的内存驻留程序.doc"可能会提供更具体的技术实现和示例代码,这对于深入理解这个主题非常有帮助。 总之,用汇编编写DOS下的内存驻留程序是一个对系统级编程有深入了解的过程。它涉及到汇编语言...
在这个模块中,我们使用dos下的中断函数和内存驻留函数来设置中断和内存驻留程序。 三、程序流程图 下面是屏保程序的流程图: 1. 初始化程序 2. 图形录入 3. 动画绘制 4. 非工作状态计时 5. 检测键盘输入 6. 中断...
通过这些文件,我们可以了解到这是一套使用汇编语言编写的内存驻留程序,可能涉及到键盘输入处理、中断服务以及程序自身的管理和激活机制。学习这些源代码可以帮助理解如何在DOS环境下有效地利用有限的内存资源,...
本文将深入探讨一个用汇编语言实现的常驻内存时钟程序,这个程序可以在计算机运行时持续显示当前时间,无需用户交互。 首先,让我们了解汇编语言的基础。汇编语言中的每条指令都对应于计算机硬件的特定机器码,...
本篇文章将深入探讨一个由汇编语言编写的时钟小程序,这个程序巧妙地利用了DOS中断,并且具有彩色显示功能,是作者为期末作业精心创作的作品。 首先,我们来理解汇编语言。汇编语言是一种符号化的机器语言,每个...
本课程设计报告的主要目的是设计和实现一个DOS下屏保程序,使用汇编语言编写该程序。该程序的主要功能是绘制屏保图形、计时、检测键盘输入和设置中断等。 汇编语言课程设计 汇编语言是一种低级编程语言,它直接...
标题中的“TSR程序作出DOS下的屏幕保护程序”指的是在DOS操作系统环境下,通过创建一个常驻系统内存(Terminable and Stay Resident, TSR)程序来实现屏幕保护功能的技术。这种程序可以在用户离开计算机或者一段时间...
在DOS环境中,开发者通常会使用汇编语言编写这样的程序,因为它们对内存管理和中断处理有更精细的控制。 **TSR程序的实现步骤** 1. **初始化**:TSR程序首先会进行一些基本的初始化工作,如分配内存、设置中断向量...
4. **编写时钟程序**:创建一个驻留在内存中的时钟程序,它能实时显示时间且不影响其他程序运行。这涉及到实时系统调用和中断处理,尤其是INT 1CH中断服务程序的修改和利用。 5. **画网格线**:根据用户输入的坐标...
第一部分是基础部分,以8086/8088为背景,以DOS和PC兼容机为软硬件平台,以MASM和TASM为汇编器,介绍汇编语言的有关概念,讲解汇编语言程序设计技术。第二部分是提高部分,以80386为背景,以新一代微处理器Pentium为...
用汇编语言(8086/DOS)实现一个显示系统时间的程序,运行时,在屏幕的右上角将显示本机系统的日期及时间,可以应用到其它适用环境中,实现其日期、时间自动更新显示功能。 知识点6:程序设计的步骤 设计的步骤包括...
`PLAY.ASM`可能是该程序的源代码,用汇编语言编写,这种低级语言直接对应机器指令,对于理解程序的工作原理非常有用。 在使用该音乐播放器时,有以下几个关键步骤: 1. **运行驻留内存的PLAY**:首先,用户需要在...
### DOS功能调用符与Debug程序调试详解 在学习计算机编程的过程中,特别是针对早期操作系统如DOS的理解,掌握DOS功能调用符...对于汇编语言学习者而言,熟练掌握这两方面知识对于理解和编写DOS下的应用程序至关重要。
- **简介**:本章介绍了如何使用汇编语言编写名为MACLIST的程序,该程序主要用于增强现有应用程序的功能。 - **功能介绍**: - 从键盘获取输入。 - 定位磁盘上的目录和文件。 - 对内存中的文件进行排序。 - 将...
这个程序需要驻留在内存中,并在屏幕上固定位置(如右上角)显示时钟,同时不影响其他程序运行。利用INT 1CH中断服务程序,每0.05秒更新一次时间显示,获取系统实时钟信息。 5. **画网格线**: 程序需根据用户...
实现这一步骤的必要性在于:一旦中断服务程序驻留内存后,一般程序员使用这一新增的中断调用就如同调用DOS或BIOS的中断子程序一样,只要了解其入口要求和返回参数就可调用。程序驻留在内存后,它占用的存储区就不会...
6. 内存管理:DOS在有限的内存资源下进行了有效的管理,如使用分配器(ALLOC.S)来分配内存,释放器(FREE.S)来回收内存。同时,通过扩展内存管理器(EMS和XMS)来利用扩展内存。 7. 多任务和并发:尽管DOS本身并...