菜鸟求助,简单的驻留程序

prince_of_ 2014-06-12 09:03:58
代码如下
stack segment para stack 'stack'
dw 100 dup ( 0 )
stack ends

code segment
assume cs:code,ds:code,ss:stack

time db 0, 0
count db 0
correct db 0
int_start:
push ax
push bx
push cx
push dx

cmp count,18 ;计数,每18次执行一次输出字符,因为改变的1c号中断,所以差不多一秒执行一次
jne exit
mov count,0

mov ah,0eh
mov bl,0
mov al,time[0] ;输出time[0]对应的数字,按照初始化应该是0
add al,48
int 10h

exit:
inc count
pop dx
pop cx
pop bx
pop ax
iret

start:
mov ax,cs
mov ds,ax ;数据初始化

mov sp,200 ;设置堆栈指针

mov dx,offset int_start
mov ax,0251ch
int 21h ;设置中断向量

mov dx,start-int_start
mov cl,4
shr dx,cl
add dx,11h
mov ah,31h
int 21h ;驻留退出

code ends
end start
下图为在xp32位机dos下执行,显示左括号ascii码为40,证明 time[0]被当成-8

下图为反汇编,time[0]和count 分别被编译为[0000]和[0002]没有问题

下图为在win7x64dosbox下直接运行的情况,未出现问题

下图为in7x64dosbox下debug运行的情况,字符值不在ascii0~255中

winxp下debug运行结果与不用debug相同,也显示左括号
查询代码段前四个字节确实为0,证明数据初始化没有问题
请问问题到底出在哪里
谢谢大神们
...全文
204 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
zara 2014-06-13
  • 打赏
  • 举报
回复
至少驻留长度的计算方法有问题,代码部分甚至都没能驻留下来,后续有程序或其它内存需要就会被侵占导致意外。
驻留程序的长度计算,要包括从 psp 到需要驻留部分的所有的大小,你这里就要包括 psp, stack 段以及 start: 之前的代码部分。通常地,为简单起见,驻留类程序都尽可能地写成 .com 类型的格式,这样计算起来就简单多了,你的代码为例,无须加上 psp (因为 .com 从 100h 起始,起码就包括了 psp),无须考虑 stack 段(因为缺省的将 stack 段放到了段的最后,你的驻留代码里也没有特意地大容量使用到堆栈)。
prince_of_ 2014-06-13
  • 打赏
  • 举报
回复
引用 6 楼 zara 的回复:
因为中断不是只在你那个 start: 后的代码里发生的,事实上,那个 start: 后代码一下子就结束了,不再运行,所以,它更可能从 dos 内部空闲模块发生,如何运行了其它程序,则可能是从那个程序里产生,这样的话,ds 就是当时的那个程序的 ds 了,也自然不是必然地指向你的 code 段,而 cs 不同,程序运行到了这里,cs 就是指向在这里;所以,需要设置 ds 指向自己的段,或者就是放弃使用 ds 而采用 cs: 段前缀来访问那些变量。
有点懂了。其他程序运行时,把ds修改了,导致不是原来的数据 没assume ds:code的时候,系统默认使用cs来寻址变量的 这样理解没错吧
zara 2014-06-13
  • 打赏
  • 举报
回复
因为中断不是只在你那个 start: 后的代码里发生的,事实上,那个 start: 后代码一下子就结束了,不再运行,所以,它更可能从 dos 内部空闲模块发生,如何运行了其它程序,则可能是从那个程序里产生,这样的话,ds 就是当时的那个程序的 ds 了,也自然不是必然地指向你的 code 段,而 cs 不同,程序运行到了这里,cs 就是指向在这里;所以,需要设置 ds 指向自己的段,或者就是放弃使用 ds 而采用 cs: 段前缀来访问那些变量。
prince_of_ 2014-06-13
  • 打赏
  • 举报
回复
引用 4 楼 zara 的回复:
exe 也可以,只是计算上稍复杂些,比不上 com 格式的干脆。 int27h,com 格式的也是一样可以使用 int21h 的 AH=31h 功能的,只是前者出现得早些,要求高些,和 com 格式的更配合;两者的区别一个是驻留长度的单位不一样,一个是 int27h 要求调用时 cs 指向 psp,这也是和 com 格式契合的,与 exe 格式有异,而后者就没有这些要求。 另外,你的代码里有对 code 段里变量的引用,但 assume 语句说明 ds 也是指向 code 段,却没有在中断部分将 ds 赋值以确实指向到 code 段,应将 ds 从 assume 语句里去掉,这样会被汇编程序自动加上 cs: 前缀以访问到那些变量;这个是数据变异的原因吧;前面的驻留长度的错误,是驻留后再运行其它程序会司机的原因。
请问 start后的部分设置了中断向量并将cs赋给了ds,在中断部分为什么还需要使ds指向cs
zara 2014-06-13
  • 打赏
  • 举报
回复
exe 也可以,只是计算上稍复杂些,比不上 com 格式的干脆。
int27h,com 格式的也是一样可以使用 int21h 的 AH=31h 功能的,只是前者出现得早些,要求高些,和 com 格式的更配合;两者的区别一个是驻留长度的单位不一样,一个是 int27h 要求调用时 cs 指向 psp,这也是和 com 格式契合的,与 exe 格式有异,而后者就没有这些要求。
另外,你的代码里有对 code 段里变量的引用,但 assume 语句说明 ds 也是指向 code 段,却没有在中断部分将 ds 赋值以确实指向到 code 段,应将 ds 从 assume 语句里去掉,这样会被汇编程序自动加上 cs: 前缀以访问到那些变量;这个是数据变异的原因吧;前面的驻留长度的错误,是驻留后再运行其它程序会司机的原因。
prince_of_ 2014-06-13
  • 打赏
  • 举报
回复
引用 1 楼 zara 的回复:
至少驻留长度的计算方法有问题,代码部分甚至都没能驻留下来,后续有程序或其它内存需要就会被侵占导致意外。 驻留程序的长度计算,要包括从 psp 到需要驻留部分的所有的大小,你这里就要包括 psp, stack 段以及 start: 之前的代码部分。通常地,为简单起见,驻留类程序都尽可能地写成 .com 类型的格式,这样计算起来就简单多了,你的代码为例,无须加上 psp (因为 .com 从 100h 起始,起码就包括了 psp),无须考虑 stack 段(因为缺省的将 stack 段放到了段的最后,你的驻留代码里也没有特意地大容量使用到堆栈)。
层主的意思是驻留程序最好不用exe,应该写成com的格式用int27驻留退出,能稍微讲一下int27h的参数作用吗
prince_of_ 2014-06-13
  • 打赏
  • 举报
回复
层主的意思是写成com的格式用int27驻留退出,能稍微讲一下int27h的参数作用吗

21,459

社区成员

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

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