鱼C论坛

 找回密码
 立即注册
查看: 88|回复: 2

[汇编作业] 为什么代码在执行过程中cs ip的内容被改变了

[复制链接]
发表于 2025-1-4 13:29:38 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
我在写王爽汇编语言的实验7时遇到一个问题


                               
登录/注册后可看大图

在循环执行第二遍时
程序在指向div指令这一步时 cs==078d ip==003d 这是对的
但是在执行完除法这一步后 cs和ip就突然变成了野指针 指向一块无关的内存 为什么
代码全文如下:

assume cs:code,ds:data
data segment
        db '1975','1976','1977','1978','1979','1980','1981','1982','1983'
        db '1984','1985','1986','1987','1988','1989','1990','1991','1992'
        db '1993','1994','1995'
       
        dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
        dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000
       
        dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
        dw 11542,14430,15257,17800
data ends

table segment
        db 21 dup ('year summ ne ?? ')
table ends

code segment
start:        mov ax,data
                mov ds,ax
                mov ax,table
                mov es,ax
                mov bx,0
                mov di,0
                mov si,0
                mov cx,21
        s:        mov ax,ds:[di]
                mov word ptr es:[bx].0h,ax
                mov ax,ds:84[di]
                mov word ptr es:[bx].5h,ax
               
               
                add di,2
                mov ax,ds:[di]
                mov word ptr es:[bx].2h,ax
                mov ax,ds:84[di]
                mov word ptr es:[bx].07h,ax
               
                mov ax,ds:168[si]
                mov word ptr es:[bx].0ah,ax
                mov ax,ds:84[si]
                mov dx,ds:84[si+2h]
                div word ptr ds:168[si]                          出错     
                mov word ptr es:[bx].0dh,ax
               
                add di,2
                add si,2
                add bx,16
                loop s
               
                mov ax,4c00h
                int 21h
code ends
end start

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2025-1-4 13:30:00 | 显示全部楼层
在您提供的代码中,`div`指令后出现CS和IP变成野指针的问题,通常是由于`div`指令出现了除零错误(Division by zero)或其他除法相关的异常。以下是可能导致该问题的几个原因以及相应解决方案:

1. **除零检查**:确保除数在执行除法之前不是0。根据代码,您使用的是`div word ptr ds:168`,请确认`ds:168`的值不为0。可以在执行`div`之前插入以下代码来检查:
cmp word ptr ds:[168], 0
   je handle_div_error

2. **结果超出范围**: 确保`div`指令的结果不会超出AX和DX寄存器的范围(16位)。如果结果可能超出范围,请缩小被除数或者增加检查机制。

3. **初始化**: 确保DX和AX寄存器在执行`div`指令前被正确赋值。DX应默认为0,除非需要使用更大的被除数:
xor dx, dx  ; Clear DX before division, if not used

4. **数据段的问题**: 确保数据和表的起始地址没有溢出,导致寻址错误。数据指针的计算方式要准确无误。

5. **指令前的偏移量和地址计算**:确保偏移量和地址计算没有错误,导致错误的内存访问。

如果CS和IP变成了野指针,极有可能是中断或异常在`div`指令执行时被触发,程序错误地跳转到未初始化的中断向量。确保保护和设置中断向量表正确,以避免此类问题。

最后,建议您通过使用调试器单步执行代码,观察`div`指令前后的寄存器状态和内存数据,以准确识别问题根源。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2025-1-4 19:10:47 | 显示全部楼层
本帖最后由 jackz007 于 2025-1-4 22:01 编辑

        应该是发生了被 0 除错误,此错误会自动触发 int 0 中断,CPU 会无条件转到 0000:0000 -  0000:0004 所登记的 4 个字节的地址处继续执行,就像执行 int 21h  中断时,CPU 会转到 0000:0084 - 0000:0088  所登记的 4 个字节的地址处继续执行一样,在 debug.exe 中,只要采用 t 命令跟踪,就可以直接跟踪到这个跳转(int 21h)。

        为了加深理解,楼主可以试一试编译、跟踪下面的代码:
ASSUME CS:CODE,DS:DATA
 
STACK SEGMENT PARA STACK 'STACK'
      DB 400H DUP(0)
STACK ENDS

DATA SEGMENT PARA PUBLIC 'DATA'
ADDR DW 0 , 0
MSG1  DB 'Bingo !', 0DH , 0AH , 'I' , 27H , 'm in INT0 now.' , 0DH , 0AH , '$' , 0
MSG2  DB 'Game Over .' , 0DH , 0AH , '$' , 0
DATA ENDS

CODE SEGMENT PARA PUBLIC 'CODE'

INT0 PROC FAR                               ; int 0 中断处理程序
      PUSH BP
      MOV BP,SP
      PUSH AX
      PUSH BX
      PUSH CX
      PUSH DX
      PUSH SI
      PUSH DI
      PUSH DS
      PUSH ES
      MOV AX,DATA
      MOV DS,AX
      MOV DX,Offset MSG1
      MOV AH,9
      INT 21H                               ; 屏显信息 MSG1
      ADD WORD PTR SS:[BP+2],2              ; 返回地址的 IP 加 2,以便越过触发 int 0 的指令(div cl),这条指令的长度为 2 个字节。 
      POP ES
      POP DS
      POP DI
      POP SI
      POP DX
      POP CX
      POP BX
      POP AX
      MOV SP,BP
      POP BP
      IRET
INT0 ENDP

SETUP PROC NEAR                             ; 安装 int 0 中断程序
      PUSH AX
      PUSH ES
      XOR AX,AX
      MOV ES,AX
      PUSH WORD PTR ES:[0]
      POP WORD PTR DS:[ADDR]
      PUSH WORD PTR ES:[2]
      POP WORD PTR DS:[ADDR + 2]
      CLI      
      MOV WORD PTR ES:[0],OFFSET INT0
      MOV WORD PTR ES:[2],CS
      STI
      POP ES
      POP AX
      RETN
SETUP ENDP

RESTORE PROC NEAR                           ; 复原 int 0 中断程序
      PUSH AX
      PUSH ES
      XOR AX,AX
      MOV ES,AX
      CLI
      PUSH WORD PTR DS:[ADDR]
      POP WORD PTR ES:[0]
      PUSH WORD PTR DS:[ADDR + 2]
      POP WORD PTR ES:[2]
      STI
      POP ES
      POP AX
      RETN      
RESTORE ENDP

MAIN PROC FAR                               ; 程序入口
      MOV AX,DATA
      MOV DS,AX
      CALL SETUP                            ; 安装 int 0 中断程序
      XOR CL,CL                             ; 除数置 0
      DIV CL                                ; 触发 int 0 中断
      CALL RESTORE                          ; 复原 int 0 中断程序
      MOV DX,OFFSET MSG2
      MOV AH,09H
      INT 21H                               ; 屏显信息 MSG2
      XOR AX,AX
      INT 16H                               ; 等待按下回车键
      MOV AX,4C00H
      INT 21H
MAIN ENDP

CODE ENDS

END MAIN 
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-1-22 18:59

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表