鱼C论坛

 找回密码
 立即注册
查看: 105|回复: 4

关于实验16的测试代码执行问题

[复制链接]
发表于 2025-3-21 15:00:08 | 显示全部楼层 |阅读模式

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

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

x
本帖最后由 laocaiye 于 2025-3-21 15:12 编辑

按照小鱼老师提供的实验16的安装程序(二)(里面的dx和di的错误点也更正了),在进行测试时,第一次执行可以出现应有的效果。但是存在以下问题:
一是中断程序只能执行一次,执行效果出现后就会定屏(一直显示),也无法正常退出DOS界面,只能强制点X关闭界面。
二是在问题一的基础上,后续设置的中断测试代码,根本就不执行。
三是同样的测试代码exe,在上次强制关闭后,在进入调试,就不在出现效果界面。
以下是测试代码

assume cs:code

code segment

start:                mov ax,0b800h
                        mov es,ax
                        mov di,0
                       
                       
                        mov ax,102h
                        int 7ch
                       
                        mov cx,25;只执行本段红色代码部分
        s0:                push cx
        s01:        mov cx,80
                        mov byte ptr es:[di],'0'
                        add di,2
                        loop s01
                        pop cx
                        loop s0

                        call delay
                       
                        mov ax,204h;蓝色测试代码不执行
                        int 7ch


                        mov ax,4c00h
                        int 21h

                       
delay:                push dx
                        push ax
                        mov dx,10h
                        mov ax,0
        s1:                sub ax,1
                        sbb dx,0
                        cmp ax,0
                        jne s1
                        cmp dx,0
                        jne s1
                       
                        pop ax
                        pop dx
                        ret
                       
code ends
end start
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2025-3-21 15:00:20 | 显示全部楼层
你的问题可能与以下几个方面有关:

1. **中断处理程序未正确返回**  
   你的代码调用 `int 7ch` 之后,可能没有正确返回,导致程序停滞。你可以检查 `int 7ch` 对应的中断处理程序是否正确执行 `iret` 返回。

2. **中断 7Ch 可能未正确注册**  
   你调用 `mov ax, 102h` 和 `mov ax, 204h` 进行中断调用,但如果 `int 7ch` 处理程序没有正确安装,可能会导致后续代码无法执行。

3. **DOS 环境下的调试问题**  
   强制关闭 DOS 窗口后,可能会导致中断向量表未恢复,影响后续的测试。建议在程序退出时,确保恢复原始的中断向量。

### 解决方案:
- **确保 `int 7ch` 处理程序正确安装**,并在 `iret` 之前正确保存和恢复寄存器。
- **在程序退出时恢复原始中断**,避免影响后续测试。
- **使用 `debug` 或 `TD`(Turbo Debugger)检查 `int 7ch` 的执行情况**,看看是否正确返回。

如果你能提供 `int 7ch` 具体的中断处理代码,我可以帮你进一步分析。

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

使用道具 举报

 楼主| 发表于 2025-3-21 15:05:01 | 显示全部楼层
以下是安装程序

assume cs:code

code segment

setbegin:        jmp short getid
        table        dw sub1,sub2,sub3,sub4
        getid:        push bx
                       
                        cmp ah,3
                        ja iretp
                       
                        mov bh,0
                        mov bl,ah
                        add bx,bx
                       
                        call word ptr table[bx]
                       
        iretp:        pop bx
                        iret
                       
sub1:                push es
                        push cx
                        push bx
                       
                        mov bx,0b800h
                        mov es,bx
                        mov bx,0
                       
                        mov cx,2000               
        lpcls:        mov byte ptr es:[bx],' '
                        add bx,2
                        loop lpcls

                        pop bx
                        pop cx
                        pop es
                        ret
                       
sub2:                push es
                        push cx
                        push bx
                       
                        mov bx,0b800h
                        mov es,bx
                        mov bx,1
                        mov cx,2000
                       
        lpfore:        and byte ptr es:[bx],11111000b
                        or es:[bx],al
                        add bx,2
                        loop lpfore
                       
                        pop bx
                        pop cx
                        pop es                       
                        ret
                       
sub3:                push es
                        push cx
                        push bx
                       
                        mov cl,4
                        shl al,cl
                       
                        mov bx,0b800h
                        mov es,bx
                        mov bx,1
                        mov cx,2000
                       
        lpbgd:        and byte ptr es:[bx],10001111b
                        or es:[bx],al
                        add bx,2
                        loop lpbgd
                       
                        pop bx
                        pop cx
                        pop es                       
                        ret
                       
sub4:                push es
                        push cx
                        push ds
                        push di
                        push si
                       
                        mov dx,0b800h
                        mov es,dx
                        mov ds,dx
                        mov di,0
                        mov si,160
                        mov cx,24
                        cld
        lpscr:        push cx
                        mov cx,160
                        rep movsb
                        pop cx
                        loop lpscr
                       
                        mov cx,80
                        mov di,160*24
        clsr:        mov byte ptr es:[di],' '       
                        add di,2
                        loop clsr
                       
                        pop si
                        pop di
                        pop ds
                        pop cx
                        pop es
                        ret               
                                       
setend:                nop

start:                mov ax,cs
                        mov ds,ax
                        mov ax,0
                        mov es,ax
                        mov di,200h
                       
                        mov si,offset setbegin
                        mov cx,offset setend - offset setbegin
                        cld
                        rep movsb
                       
                        cli
                        mov word ptr es:[7ch*4],0
                        mov word ptr es:[7ch*4+2],20h
                        sti
                       
                        mov ax,4c00h
                        int 21h
                       
code ends

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

使用道具 举报

发表于 2025-3-21 15:05:15 | 显示全部楼层
laocaiye 发表于 2025-03-21 15:05
以下是安装程序

assume cs:code

code segment
...


It looks like you're implementing a custom interrupt handler at `int 7Ch`, but you're encountering issues where the interrupt only executes once, the screen freezes, and subsequent executions do not work. Let's analyze the potential causes and solutions.

---

### **Potential Issues**
1. **Interrupt Handler Not Properly Installed**
   - Your installation code copies the interrupt handler to `0:200h`, but it does not properly set the interrupt vector for `int 7Ch`. Instead, it modifies `es:[0]` and `es:[2]`, which are likely affecting `int 00h` (Divide by Zero Exception) instead of `int 7Ch`.

2. **Interrupt Handler Not Returning Properly**
   - The handler should end with `iret`, which it does in `iret` at `iret: pop bx iret`. However, if the interrupt is not properly installed, it may not be executing at all.

3. **Interrupt Handler Overwriting Memory**
   - The handler modifies video memory (`0xB8000`), but if `di` is not properly managed, it could be writing outside the intended range.

4. **Interrupt Vector Not Restored**
   - If the program is forcefully closed, the interrupt vector remains pointing to an invalid memory location, causing subsequent executions to fail.

---

### **Suggested Fixes**
#### **1. Properly Set the Interrupt Vector**
Modify your installation code to correctly set `int 7Ch` in the interrupt vector table:
mov ax, 0
mov es, ax
mov word ptr es:[7Ch * 4], 200h  ; Offset of handler
mov word ptr es:[7Ch * 4 + 2], 0 ; Segment of handler
This ensures that `int 7Ch` correctly points to your handler.

#### **2. Ensure the Handler Returns Properly**
Your handler should always end with `iret` to return control to the calling program.

#### **3. Restore the Original Interrupt Vector on Exit**
Before exiting, restore the original interrupt vector to prevent issues in subsequent runs.

---

### **Next Steps**
- Try modifying your installation code to correctly set `int 7Ch`.
- If the issue persists, use a debugger (`debug.exe` or `TD`) to inspect the interrupt vector at `int 7Ch` (`d 0:7C*4`).
- If you still encounter issues, let me know what happens when you run `int 7Ch` manually in a debugger.

Would you like me to provide a corrected version of your installation code?

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

使用道具 举报

 楼主| 发表于 2025-3-21 15:12:34 | 显示全部楼层
看样子老头子还要先学习英语,算了。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-3-31 08:52

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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