当前位置: 代码迷 >> 汇编语言 >> 初学者,简单的驻留程序
  详细解决方案

初学者,简单的驻留程序

热度:131   发布时间:2016-05-02 04:32:59.0
菜鸟求助,简单的驻留程序
代码如下
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,证明数据初始化没有问题
请问问题到底出在哪里
谢谢大神们
------解决方案--------------------
因为中断不是只在你那个 start: 后的代码里发生的,事实上,那个 start: 后代码一下子就结束了,不再运行,所以,它更可能从 dos 内部空闲模块发生,如何运行了其它程序,则可能是从那个程序里产生,这样的话,ds 就是当时的那个程序的 ds 了,也自然不是必然地指向你的 code 段,而 cs 不同,程序运行到了这里,cs 就是指向在这里;所以,需要设置 ds 指向自己的段,或者就是放弃使用 ds 而采用 cs: 段前缀来访问那些变量。
  相关解决方案