首页
社区
课程
招聘
[求助]8086汇编的一个问题,大家帮忙看看谢谢!
发表于: 2013-5-23 23:05 5228

[求助]8086汇编的一个问题,大家帮忙看看谢谢!

2013-5-23 23:05
5228
do0:                jmp short s1
                        db "error!", 0
                       
                        s1:
                                                push ax
                        push cx
                        push di
                        push si
                       
                        mov ax, 0b800h
                        mov es, ax
                        mov di, 160*10
                       
                        mov ax, 0
                        mov ds, ax
                        mov si, 202h
                       
                        mov ch, 0
                        s2:
                        mov cl, ds:[si]
                        jcxz ok
                        mov es:[di], cl
                        mov es:[di].1, BYTE ptr 2
                        inc si
                        add di, 2
                        jmp short s2
                       
                        ok:
                        pop si
                        pop di
                        pop cx
                                                pop ax
                        iret
这段代码加了 push ax    pop ax 就卡死不动了,不加的话就正常
如果加了push ds  push es pop es pop ds返回后ds和es的值不是以前的
求解!

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (10)
雪    币: 246
活跃值: (91)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
2
没有DOS汇编好多年...
建议用DEBUG命令调试下。
2013-5-23 23:14
0
雪    币: 34
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
下面的问题我解决了,现在就是push ax的问题
我分析了下
mov ax, 0ffffh
mov bl, 1

div bl
产生溢出,执行中断子程序
然后我中断子程序中push ax
这时候ax的值是多少,为什么会崩掉??
2013-5-23 23:17
0
雪    币: 807
活跃值: (2298)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
作为中断服务程序,一开始必须要把所有的寄存器都入栈,退出时再全部恢复,如果必要,甚至需要考虑切换到自己的堆栈。

do0:  jmp short s1

str1: db "error!", 0
      
s1:
      push ax
      push bx
      push cx
      push dx
      push si
      push di
      push ds
      push es

      push cs
      pop ds
      mov ax,0b800h
      mov es,ax
      lea si,str1
      mov di,160*10
      cld
s2:
      lodsb
      or al,al
      jz s3
      mov ah,7
      stosw
      jmp short s2
s3:
      pop es
      pop ds
      pop di
      pop si
      pop dx
      pop cx
      pop bx
      pop ax
      iret

    试试看这个能否正常。
2013-5-24 01:46
0
雪    币: 34
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
感谢你的回答,但是我现在的问题是
当div bl的时候(ax = 0ffffh,bx = 1)产生溢出,执行中断子程序
我在中断子程序中把ax入栈,问题就发生了,如果不push ax的话就没有问题,现在我想知道
当div bl溢出的时候ax的值是多少?push ax怎么会出现这种情况?
2013-5-24 10:37
0
雪    币: 807
活跃值: (2298)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
楼主可以试试下面的代码,已经在 MASM 6.11 环境下编译通过,程序没有设置堆栈段,编译完成后,必须用 exe2bin.exe 命令把 .exe 类型的程序转换为 .com 类型。

<--- 以下代码开始
CODE SEGMENT PARA

     ASSUME CS:CODE,DS:CODE,ES:CODE

     ORG 100H

START: jmp BEGIN

     IPD DW 00
     CSD DW 00

     MSG db 0ah,0dh,0ah,0dh,"       operation caused a devide overflow error !",0ah,0dh,0ah,0dh,"$",00

Int0:
      push bp
      mov bp,sp
      push ax
      push dx
      push ds
      inc word ptr[bp+2]
      inc word ptr[bp+2]
      push cs
      pop ds
      lea dx,MSG
      mov ah,09h
      int 21h      
      pop ds
      pop dx
      pop ax
      mov sp,bp
      pop bp
      iret

GetI:
      push bp
      mov bp,sp
      push ax
      push bx
      push si
      push ds
      xor ax,ax
      mov ds,ax
      xor si,si
      mov bx,[si]
      mov ax,[si+2]
      mov [bp+4],ax
      mov [bp+6],bx
      pop ds
      pop si
      pop bx
      pop ax
      mov sp,bp
      pop bp
      retn

SetI:
      push bp
      mov bp,sp
      push ax
      push bx
      push si
      push ds
      xor ax,ax
      mov ds,ax
      xor si,si
      mov ax,[bp+4]
      mov bx,[bp+6]
      cli
      mov [si],bx
      mov [si+2],ax
      sti      
      pop ds
      pop si
      pop bx
      pop ax
      mov sp,bp
      pop  bp
      retn

BEGIN:
      push ax
      push bx
      call GetI
      pop bx
      pop ax
      mov IPD,ax
      mov CSD,bx

      mov ax,offset Int0
      mov bx,cs
      push ax
      push bx
      Call SetI
      add sp,4

      mov ax,0ffffh
      mov cl,1
      div cl

      mov ax,IPD
      mov bx,CSD
      push ax
      push bx
      Call SetI
      add sp,4

      mov ax,4c00h
      int 21h

CODE ENDS

END START
<--- 以上代码结束

    当中断发生时,所有寄存器均维持原样没有任何问题,问题是返回地址指向 div cl 指令,如果不处理,中断返回后,还将继续执行 div cl 指令,程序将会陷入死循环。所以,在中断处理程序中,需要把返回地址的 IP 值增加 2(因为 div cl 指令长度为 2  个字节),以保证中断返回后,从 div cl 的下一条指令处继续执行。
2013-5-24 18:58
0
雪    币: 31
活跃值: (48)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
7
当div bl的时候(ax = 0ffffh,bx = 1)产生溢出,执行中断子程序我在中断子程序中把ax入栈,问题就发生了,如果不push ax的话就没有问题,现在我想知道当div bl溢出的时候ax的值是多少?push ax怎么会出现这种情况?
这样肯定溢出啦,因为65535/1的结果al放不下。
2013-5-24 19:20
0
雪    币: 34
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8


非常感谢你,我等好好看看,可否留个Q?
2013-5-24 19:20
0
雪    币: 34
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
对 但是我push ax就陷入死循环
2013-5-24 19:22
0
雪    币: 807
活跃值: (2298)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
从贴出的中断处理代码看,楼主并没有专门处理返回地址,程序必然会陷入死循环,与 push eax 指令本身无任何关系!计算机程序遵循严密的逻辑,是最完美的科学,楼主不要迷信,要相信科学!

    如果楼主喜欢坚持自己的代码,那就适当增加几行代码看看问题是否能够得到解决

do0:    jmp short s1
        db "error!", 0
      
s1:

; 新增代码开始

      push bp
      mov bp,sp
      inc word ptr[bp+2]
      inc word ptr[bp+2]

; 新增代码结束

      push ax
      push cx
      push di
      push si
      
      mov ax, 0b800h
      mov es, ax
      mov di, 160*10
      
      mov ax, 0
      mov ds, ax
      mov si, 202h
      
      mov ch, 0
s2:
      mov cl, ds:[si]
      jcxz ok
      mov es:[di], cl
      mov es:[di].1, BYTE ptr 2
      inc si
      add di, 2
      jmp short s2
      
ok:
      pop si
      pop di
      pop cx
      pop ax

; 新增代码开始

      mov sp,bp
      pop bp

; 新增代码结束

      iret
2013-5-24 19:56
0
雪    币: 34
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
这个我看懂了, 因为int 中断后 将cs和ip入栈
然后你将bp = sp,bp默认与ss配合,将bp+2处的word型数据也就是返回的ip长度+2
,但是读取div bl 后ip不是指向下一条指令处了吗,为什么返回后还会到div bl处?难道ip没有增加?
2013-5-24 20:13
0
游客
登录 | 注册 方可回帖
返回
//