在XV6 8086实模式0x13 VGA下高效复制单字节到多内存地址
实模式0x13下高效绘制填充矩形与垂直线方案
核心思路:利用x86字符串指令实现无预分配的连续内存填充
实模式下x86的rep stosb指令是专门为重复存储字节设计的硬件加速指令,完全符合你"无需预分配大空间、动态复制单字节到连续内存"的需求,效率远高于逐像素写入。
1. 连续内存块填充(水平线/矩形单行)
直接用rep stosb实现指定长度的连续像素填充,以复制18个字节(像素)为例:
; 初始化段寄存器:ES指向VGA内存段(0xA000段对应物理地址0xA0000) mov ax, 0xA000 mov es, ax ; 设置参数 mov al, 0x0B ; 像素颜色值11(十六进制0x0B) mov di, 0x1234 ; 目标起始偏移(对应物理地址0xA0000+0x1234) mov cx, 18 ; 要填充的字节(像素)数量 ; 执行填充:硬件加速,自动重复将AL写入[ES:DI],共CX次,DI自动递增 rep stosb
2. 填充矩形
矩形需逐行处理,每行通过计算起始偏移后调用rep stosb填充:
; 矩形参数:x1=10, y1=20, x2=27, y2=30(宽度18,高度11) mov ax, 0xA000 mov es, ax ; ES绑定VGA内存段 mov cx, 11 ; 矩形总高度(行数) mov bx, 20 ; 当前行的y坐标 rect_loop: ; 计算当前行的起始偏移:偏移 = y*320 + x1 mov ax, bx mov dx, 320 mul dx ; AX = y*320(320*200=64000 < 65536,无需处理DX) add ax, 10 ; 加上x1=10,得到起始偏移 mov di, ax mov al, 0x0B ; 设置颜色值 mov cx, 18 ; 当前行的像素宽度 rep stosb ; 填充整行 inc bx ; 切换到下一行 loop rect_loop ; 循环直到所有行填充完成
3. 绘制垂直线
垂直线的像素地址间隔320字节(每行宽度),无法用连续填充,需循环逐个写入:
; 垂直线参数:x=50, y1=10, y2=40(共31个像素) mov ax, 0xA000 mov es, ax mov cx, 31 ; 垂直线总像素数 mov bx, 10 ; 当前y坐标 vert_loop: ; 计算当前像素偏移:偏移 = y*320 + x mov ax, bx mov dx, 320 mul dx add ax, 50 mov di, ax mov al, 0x0B ; 设置颜色值 stosb ; 写入单个像素 inc bx ; 下一个y坐标 loop vert_loop ; 循环直到所有像素写入完成
关键注意点
- 必须确保
ES寄存器指向0xA000段,对应VGA 320x200 8位模式的物理内存基址0xA0000 rep stosb是硬件加速指令,效率远高于手动循环逐像素写入,且完全不需要预分配数组或使用.string伪指令- 计算偏移时,因320*200=64000小于65536,16位乘法
mul dx的结果仅存于AX,无需处理DX寄存器
内容的提问来源于stack exchange,提问作者Alexander Griffin
相关产品推荐
相关产品推荐

