探究dosbox打印字符时的bug问题
程序员文章站
2024-03-07 22:08:03
...
程序代码
assume cs:code,ds:data
data segment
db 10 dup(0)
;运行完程序后数据分布为36 36 36 32 31
data ends
code segment
;g001b程序运行结束
start:mov ax,12666
mov bx,data
mov ds,bx;ds=data
;ds = 076a
mov si,0;si = 0
call dtoc
;看运行到mov dh,8时ip的值
mov dh,8;等第一个函数运行完之后
;再放入第二个运行函数
mov dl,3
mov cl,2;cl为对应的颜色
mov di,si;si为循环次数
;push之前ss = 0769,sp = 0000
;push之后ss = 0769,sp = fffe
;push si;
mov si,0;将si设置为起始位置
;运行到call show_str之前时可以
;直接设置g 0019
call show_str
;使用call show_str之后ss = 0769,sp = fffc
;这说明压栈的时候必须指定内存空间,不能
;压栈之后调用一个函数再出栈
mov ax,4c00h
int 21h
dtoc: mov bx,10
;bl = 0ah
s1:mov dx,0
div bx
;8086除法指令正确执行有条件
;被除数的高位寄存器数值,必须小于除数
;如果出现??? [BX+SI]的结果,说明这一步
;出现了除法的溢出,使用div bl指令会出现除法溢出
;12666/10 = 1266,而1266>2的8次方-1=256
;所以8位寄存器存不下1266
mov cx,ax;商放在cx寄存器之中
;方便后面的jcxz判断
;第一次循环,dx = 0006(余数),ax = 04F2(商)
;第二次循环,dx = 0006(余数),ax = 007E(商)
add dl,30h;将dl加上30h形成ascii码
;第一次循环,dx = 0036
;第二次循环,dx = 0036
mov ds:[si],dl;将dl的内容放入data:[si]中
;ax继续存储商,接着运行下一步
inc si
jcxz ok
jmp short s1
ok:ret
show_str:
;函数功能:将相应的字符以ascii码的形式显示出
mov bx,0b800h;显示图像的区域
mov es,bx
;es = b800h
;下面几行代码实现mov bp,dh*160+dl
mov ah,dh
mov al,160
mul ah
mov dh,0000
add ax,dx
mov bp,ax;这一段代码实现了mov bp,dh*160+dl功能
;bp = 0503
mov dl,cl;将颜色赋值给dl寄存器
;dl = 0002
mov cx,di;设置循环次数,
;程序的bug,cx出来时数据错误
;cx = 001B
;mov cx,0006h时可以全显示出来
;该用di传输数据时就无法显示出来字符串了。。。
;这一句改为mov cx,di时就无法显示字符串
;di = 0005h,cx = 0005h
;di设置为0006h时才能全部显示,di设置为0005h时无法全部显示
;之前这段改为pop cx可以运行出来数据
;改为mov cx,di就不可以运行出来数据
;pop cx
s:mov bh,ds:[si];高位存储ascii码
mov bl,dl;低位存储颜色
;bx = 0257
;显示数据:36 36 36 32 31
mov es:[bp],bx
inc si
add bp,2
loop s
ret
code ends
end start
;结论,采用g命令调试的时候对于打印字符串来说不易显示正确
;直接输入t17时直接运行exe文件
这里打印dosbox貌似出了点bug,本来应该显示的是全是绿色的6621数字的,但是打印出来后最后一个数字1变成了白色
上一篇: Android实现自定义的卫星式菜单(弧形菜单)详解
下一篇: 打印字符
推荐阅读