织芜 2024-04-21 16:10 采纳率: 70.8%
浏览 3

汇编语言自制中断出错

汇编语言自制7ch号中断,实现清屏,改变前景色后景色等功能,可是测试后发现没有效果

assume cs:codesg,ss:stacksg

stacksg segment
    db 128 dup(0)
stacksg ends

codesg segment
start:
    mov ax,stacksg
    mov ss,ax
    mov sp,128

    ;install
    mov ax,cs
    mov ds,ax
    mov si,offset int7ch
    mov ax,0
    mov es,ax
    mov di,200H
    mov cx,offset int7chend-offset int7ch

    cld
    rep movsb

    mov ax,0
    mov es,ax
    mov es:[7ch*4], 200h
    mov es:[7ch*4+2],0

    mov ax,0204H
    int 7ch

    mov ax,4c00h
    int 21h

int7ch: ;ah功能号
    jmp short int7chmain
    table   dw offset clscreen-offset int7ch+200h
            dw offset setfront-offset int7ch+200h
            dw offset setbackground-offset int7ch+200h
            dw offset rollup-offset int7ch+200h
int7chmain:
    push bx
    cmp ah,4
    ja int7chret
    mov bh,0
    mov bl,ah
    jmp word ptr cs:[bx+202h]
clscreen:
    push ds
    push si
    push ax
    push cx
    mov ax,0b800h
    mov ds,ax
    mov si,0
    mov cx,80*25
    clscreenloop:
        mov byte ptr ds:[si],' '
        add si,2
        loop clscreenloop
    pop cx
    pop ax
    pop si
    pop ds
    jmp int7chret
setfront:   ;al 颜色
    push ds
    push si
    push ax
    push cx
    mov ax,0b800h
    mov ds,ax
    mov si,1
    mov cx,80*25
    setfrontloop:
        and byte ptr ds:[si],11111000b
        or byte ptr ds:[si],al
        add si,2
        loop setfrontloop
    pop cx
    pop ax
    pop si
    pop ds
    jmp int7chret
setbackground:
    push ds
    push si
    push ax
    push cx
    mov ax,0b800h
    mov ds,ax
    mov si,1
    mov cx,80*25
    setbackgroundloop:
        and byte ptr ds:[si],00011111b
        shl al,1
        shl al,1
        shl al,1
        shl al,1
        or byte ptr ds:[si],al
        add si,2
        loop setbackgroundloop
    pop cx
    pop ax
    pop si
    pop ds
    jmp int7chret
rollup:
    push ds
    push si
    push es
    push di
    push ax
    push cx
    mov ax,0b800h
    mov ds,ax
    mov es,ax
    mov si,160
    mov di,0
    mov cx,160*24
    cld
    rep movsb
    pop cx
    pop ax
    pop di
    pop es
    pop si
    pop ds
    jmp int7chret
int7chret:
    pop bx
    iret
int7chend:nop

codesg ends

end start
  • 写回答

5条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-04-21 16:10
    关注

    引自免费微信小程序:皆我百晓生

    在分析您的汇编程序后,我发现了一些可能的问题。首先,您安装中断处理程序的方法不正确。在实模式下,正确的做法是将中断向量表(IVT)中的地址设置为中断服务例程的入口点。下面是修改后的代码,包括一个更正的中断安装方法:

    ; ... (保持之前的代码不变)
    
    ; 安装中断
    mov ax, cs
    mov ds, ax
    mov si, offset int7ch
    mov ax, offset int7ch ; 这里应该是中断服务例程的地址
    mov [es:7CH*4], ax
    mov [es:7CH*4+2], word ptr cs:offset int7chmain-2 ; 减去2是因为指令长度为2字节
    
    ; ... (其余部分保持不变)
    

    此外,您提到要实现的功能是清屏、改变前景色和背景色等,但是您在中断处理程序中使用了cmp ah, 4来进行判断,而通常情况下,BIOS中断调用的AH寄存器不会总是包含值4。为了确保这些功能正常工作,您应该根据实际功能更改中断处理程序的逻辑。

    例如,您可以使用以下代码替换int7chmain,并添加一些额外的函数来处理特定的功能:

    int7chmain:
        push ax
        push bx
        push cx
        push dx
    
        mov ah, 0 ; 清除AH寄存器,以便于后续检查功能码
        mov al, bh ; 将原AH值保存到AL中,用于之后的比较
        cmp al, 0 ; 检查是否为0,如果是,则执行清屏操作
        je clscreen
        cmp al, 1 ; 检查是否为1,如果是,则执行前景颜色设置操作
        je setfront
        cmp al, 2 ; 检查是否为2,如果是,则执行背景颜色设置操作
        je setbackground
        cmp al, 3 ; 检查是否为3,如果是,则执行滚动操作
        je rollup
    
        ; 如果没有匹配的功能码,返回默认操作
        jmp int7chret
    
    clscreen:
        call clscreen
        jmp int7chret
    
    setfront:
        call setfront
        jmp int7chret
    
    setbackground:
        call setbackground
        jmp int7chret
    
    rollup:
        call rollup
        jmp int7chret
    
    int7chret:
        pop dx
        pop cx
        pop bx
        pop ax
        iret
    

    然后,更新每个功能函数的名称,以便与中断处理程序中的调用相匹配:

    clscreen proc near
        ; ...
    clscreen endp
    
    setfront proc near
        ; ...
    setfront endp
    
    setbackground proc near
        ; ...
    setbackground endp
    
    rollup proc near
        ; ...
    rollup endp
    

    这样,当您通过int 7Ch调用中断时,可以传递不同的功能码(例如,0、1、2或3),并由中断处理程序根据功能码执行相应的操作。

    注意:这个例子适用于DOS环境下的实模式编程,现代操作系统(如Windows)通常不允许用户自行修改中断向量表,因此上述代码仅在复古计算机或仿真环境中有效。如果您在现代环境下尝试运行此代码,可能会导致系统不稳定或无响应。

    评论 编辑记录

报告相同问题?

问题事件

  • 创建了问题 4月21日

悬赏问题

  • ¥15 curl 命令调用正常,程序调用报 java.net.ConnectException: connection refused
  • ¥20 关于web前端如何播放二次加密m3u8视频的问题
  • ¥20 spring boot集成mqtt的使用问题
  • ¥15 使用百度地图api 位置函数报错?
  • ¥15 metamask如何添加TRON自定义网络
  • ¥66 关于川崎机器人调速问题
  • ¥15 winFrom界面无法打开
  • ¥30 crossover21 ARM64版本安装软件问题
  • ¥15 mymetaobjecthandler没有进入
  • ¥15 mmo能不能做客户端怪物