Assembly 8086汇编视频存储器
我正在用16位TASM做一个项目,其中很大一部分涉及到广泛地访问视频内存。项目处于320x200x256 VGA模式,我正在通过Dosbox运行它 例如,我有以下一组指令,用于在程序开始时填充/擦拭屏幕:Assembly 8086汇编视频存储器,assembly,dos,video-memory,Assembly,Dos,Video Memory,我正在用16位TASM做一个项目,其中很大一部分涉及到广泛地访问视频内存。项目处于320x200x256 VGA模式,我正在通过Dosbox运行它 例如,我有以下一组指令,用于在程序开始时填充/擦拭屏幕: GFXMode proc ;Initialize 256-Color Graphics Mode [Args: None] [Returns: None] push ax mov ax, 0013h int 10h mov ax, 0a000h m
GFXMode proc ;Initialize 256-Color Graphics Mode [Args: None] [Returns: None]
push ax
mov ax, 0013h
int 10h
mov ax, 0a000h
mov es, ax
pop ax
ret
GFXMode endp
RefreshOff proc ;Disables screen refresh while drawing [Args: None] [Returns: None]
push ax bx
mov ax, 1201h
mov bl, 36h
int 10h
pop bx ax
ret
RefreshOff endp
FillScreen proc ;Fills screen with a certain color [Args: 8-bit Color] [Returns: None]
push bp
mov bp, sp
push ax bx
mov al, ss:[bp + 4] ;Color
mov bx, 0h
_fillScreenNextPixel:
mov es:[bx], al
inc bx
cmp bx, 0ffffh
jb _fillScreenNextPixel
pop bx ax bp
ret 2
FillScreen endp
RefreshOn proc ;Shows changes on screen [Args: None] [Returns: None]
push ax bx
mov ax, 1200h
mov bl, 36h
int 10h
pop bx ax
ret
RefreshOn endp
而函数FillScreen通常为0FFh,因此它应该是白色的
自从我与TASM合作以来,我一直在使用Turbo Debugger进行调试,因为它们结合在一起。一些非常奇怪的事情发生了——我可以在调试器中按F7逐行前进,也可以按F9跳到最后。所以我在看es段的内容(在两种情况下都设置为A000),两次分开,一次点击F9,然后按住F7(直到我再也忍不住按住)
当我点击F9时,屏幕上会显示所有内容,但视频内存没有分配任何内容。一点也不。在程序结束时,我检查es中是否有任何内容,并且都是零
当我按住F7几分钟时,我可以看到值被放置在寄存器中,因此我知道它们在那里,但是当我在几百像素后停止按住键并让它离开时,值就停止被分配。当我看到屏幕时,它是半种颜色和半种颜色
我不知道这是否是我的调试器或dosbox或代码中的某个问题,但我必须将这些值保留在某个位置,以便以后可以访问它们。基本上,我的程序到底出了什么问题
编辑:我没有代表发布图像,所以如果我将F7保持为0x600像素,然后放弃颜色0x3B,情况就是这样。中线只出现在意外点击< P>如果你在BES中使用B800而使用DI,而不是BX,那么你可能会有更多的运气
mov es:[di], al
inc di
cmp di, 0ffffh
也可能有助于停在F9FF,而不是FFFF(可能需要抖动该数字)
我已经测试了你的代码的底部,如果你调整它就可以了,屏幕上会有一个颜色飞溅
mov bx,B800
mov es,bx
mov bp,sp
ss:mov al,[bp+4]
mov di,0
NextPixel
es:mov [di],al
inc di
cmp di,FFF
jb NextPixel
mov ax,1200
mov bl,36
int 10
但是刷新暂停位做了一些奇怪的事情,我排除了它
如果你被困在A000内存中,那就足够了,但是es:di是配对的你的视频内存位置是什么?B800:xxxx是通常的输出2-这是什么意思?pop bx ax bp看起来很方便,以前没见过你没有告诉我们你在哪里给
es
赋值,所以很难说它在程序中的某个点上是否会有某个值。顺便说一句,通过使用REP STOSB
,您可以大大简化FillScreen
过程。此处分配了一个值-mov es:[bx],al
,不过如果您需要段分配,我也添加了该值。这实际上是屏幕记忆,我不明白为什么它不记得屏幕上的内容。是的,我指的是片段分配。如果GFXMode
是您在程序中向es
写入代码的唯一位置,那么假设调用了GFXMode
,那么当您进入程序时,我看不出它怎么会有0
值。除非你在某个地方有一个bug,导致跳转到某个随机位置并执行垃圾。OP使用的是图形模式,其中屏幕段为0A000h,因此使用文本模式段(如0B800h)毫无意义。ES:DI是核心内存操作中的常见约定,因为使用它的字符串指令,然而,我看到ES:BX在图形代码中使用了相当多的一点。