You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自制OS中draw_line函数仅绘首尾像素,中间像素缺失求助

自制OS中draw_line仅绘制首尾像素的问题修复

问题根源

  1. put_pixel破坏了输入寄存器ecx
    put_pixel函数中执行imul ecx, ecx, 320时,直接修改了传入的pos_y参数(ecx寄存器)。draw_line循环依赖ecx保持初始的y坐标不变,第一次调用put_pixel后ecx的值变为y*320,后续循环计算的像素位置完全错误,导致线条中间的像素被绘制到屏幕外或不可见区域。

  2. 像素写入长度错误
    VGA模式0x13是320x200的256色模式,每个像素仅占用1字节。但代码中使用mov [edi], eax写入4字节数据,会覆盖当前像素后的3个像素,进一步导致线条显示异常。

修复方案

1. 保护输入寄存器ecx

在put_pixel中先将ecx的值压栈保存,计算完成后再恢复,避免破坏原参数:

put_pixel:
    push ecx       ; 保存pos_y到栈

    mov edi, GRAPHICS_MEMORY
    imul ecx, ecx, 320
    add edi, ecx
    add edi, eax

    mov al, bl     ; 取颜色的低8位(256色模式只需1字节)
    mov [edi], al  ; 仅写入1字节,避免覆盖其他像素

    pop ecx        ; 恢复pos_y
    ret

2. 修正像素写入操作

将mov [edi], eax改为mov [edi], al,只写入1字节的颜色值,适配VGA模式0x13的像素格式。

3. 验证draw_line逻辑

draw_line的循环逻辑本身没问题,但需要确保寄存器不被后续调用破坏。修复put_pixel后,循环中eax(x坐标)递增、edx(长度)递减的逻辑就能正常工作,绘制出完整的水平线。

修改后的完整put_pixel与draw_line代码

;------------------------------
;   put_pixel method          
;   Plot a pixel on the screen
;   Arguments:                
;   eax - pos_x               
;   ecx - pos_y               
;   ebx - color               
;-----------------------------|
put_pixel:
    push ecx                       ; 保存原y坐标,避免被修改

    mov edi, GRAPHICS_MEMORY       ; 图形内存基地址
    imul ecx, ecx, 320             ; 计算y方向偏移(320像素/行)
    add edi, ecx                   ; 加上y偏移
    add edi, eax                   ; 加上x偏移

    mov al, bl                     ; 提取8位颜色值
    mov [edi], al                  ; 写入单个像素

    pop ecx                        ; 恢复原y坐标
    ret                            ; 返回

; eax = pos x, ecx = pos y, edx = width, ebx = color
draw_line:
    cmp edx, 0
    je exit

    call put_pixel
    inc eax
    dec edx
    jmp draw_line
exit:
    ret

内容的提问来源于stack exchange,提问作者XICreations

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 05:12:03