自制OS中draw_line函数仅绘首尾像素,中间像素缺失求助
自制OS中draw_line仅绘制首尾像素的问题修复
问题根源
put_pixel破坏了输入寄存器ecx
put_pixel函数中执行imul ecx, ecx, 320时,直接修改了传入的pos_y参数(ecx寄存器)。draw_line循环依赖ecx保持初始的y坐标不变,第一次调用put_pixel后ecx的值变为y*320,后续循环计算的像素位置完全错误,导致线条中间的像素被绘制到屏幕外或不可见区域。像素写入长度错误
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
相关产品推荐
相关产品推荐

