【问题标题】:8086 Assembly Video Memory Discrepancy8086 装配视频内存差异
【发布时间】:2013-06-18 19:56:27
【问题描述】:

我正在开发一个 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
    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 或我的代码中的某些东西的问题,但我必须将这些值保存在某个地方,以便以后可以访问它们。基本上,我的程序到底是怎么回事?

编辑:我没有代表发布图像,所以http://puu.sh/3iKhw.png 是我按住 F7 为 0x600 像素然后松开颜色为 0x3B 时的样子。中间的那条线是误点击才出现的

【问题讨论】:

  • 你的显存位置是什么? B800:xxxx 是通常的输出
  • ret 2 - 这是什么意思? pop bx ax bp 看起来很方便,以前没见过
  • 您没有向我们展示您将值分配给es 的位置,因此很难说它是否应该在程序中的某个点具有某个值。顺便说一句,您可以使用REP STOSB 大大简化您的FillScreen 过程。
  • 这里分配了一个值 - mov es:[bx], al 虽然如果你想要段分配我也添加了。它实际上是屏幕记忆,我不明白为什么它不记得屏幕上的内容。
  • 是的,我的意思是分段分配。如果GFXMode 是您在程序中写入es 的唯一位置,我看不出它在您进入程序时如何具有0 的值,假设GFXMode 已被调用。除非你在某个地方遇到了导致跳转到某个随机位置并执行垃圾的错误。

标签: assembly dos video-memory


【解决方案1】:

如果你把B800粘在es里,用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 是一对

【讨论】:

  • OP 使用的是 图形模式,其中屏幕段为 0A000h,因此使用像 0B800h 这样的文本模式段没有意义。
  • ES:DI 是核心内存操作中的常见约定,因为字符串指令使用它,但是我看到 ES:BX 在图形代码中使用了很多。
猜你喜欢
  • 2021-07-04
  • 2018-06-17
  • 2014-04-15
  • 1970-01-01
  • 1970-01-01
  • 2011-06-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多