将控制台遮阳板内容保存到数组中(程序集)

Save Console visor content into an Array (Assembly)

我正在学校开始学习一门新语言(汇编),我需要为此做一些工作 class。我正在开发 DOSBox 0.74。 我需要一个函数来将所有控制台内容遮阳板保存到一个数组中,但我该怎么做呢? 我试过了,

salva_ecran proc
        xor     bx,bx
        mov     cx,25*80

salva:          
        mov dl, es:[bx]
        mov consoleText[bx], dl
        inc bx
        cmp bx, cx
        jb salva
        ret
salva_ecran endp

但是没用。我的变量是 consoleText db 80 dup ( 25 dup (?),13,10 ).

ps.: 我在这方面真的很陌生,如果问题很荒谬或者代码不好而且效率低下,我很抱歉。

consoleText 定义为 80x27 字节(不是 25x82!),而那些 13,10 无论如何都是无用的,因为你将用 mov consoleText[bx], dl 覆盖它们,所以你需要的存储是 consoleText db 80*25 dup (?).

mov dl, es:[bx] 可以读取文本模式的视频 RAM,如果 es 设置为 0B800h(从您的代码中看不到)。

但是 80x25 的文本模式视频 RAM(我认为是模式 03h)确实每个字符使用两个字节,一对的第一个字节是扩展的 ASCII 码,第二个字节是带有颜色的属性,大概见 https://en.wikipedia.org/wiki/VGA-compatible_text_mode 和其他资源。所以你只阅读一半的字符和一半的颜色,只阅读我认为 mov dl, es:[bx*2] 可以在实模式下工作的所有字符(或者使用 si 而不是 bx,以防 16b real模式不能使用bx*2寻址模式)。

新行在上一行之后的视频内存中开始,视频 RAM 中没有 13,10,实际上这些是有效的字体字形(13 是音符 IIRC),所以前 160 个字节位于 B800:0000 是第一行 80 个字符(带颜色),然后在地址 160 (B800:00A0) 第二行立即开始。

不清楚你是如何verify/print存储的内容,所以很难说"didn't work"是什么。始终使用调试器来验证您是否按预期获得了值。

对于 save/restore 全文模式 VRAM 你当然应该存储颜色(所以 80*25*2 字节缓冲区),并像那样恢复它们,只有当 运行 应用程序不会更改 VRAM 或其他 VGA 控制寄存器的开头,从而影响输出(即仅处于原始 mov ax,3 int 10h 状态)。同样 store/restore 不会恢复 BIOS 光标位置和可能的其他 BIOS 变量,所以如果你想真正保存 "console",除了复制 VRAM 内容之外还有更多的事情要做。

但总的来说,这看起来是一个不错的尝试,代码简单且切中要害,学习基础知识时不要担心性能。但是学习如何有效地使用调试器对您的未来(汇编学习)至关重要。

屏幕上的字符成对出现:字符和颜色,因此您只需将变量大小(和计数器!)加倍即可:

.model small
.stack 100h
.data

some_text   db 'Whosebug!',13,10,'$'  
consoleText db 80*25*2 dup(?)  ;◄■■ * 2

.code
  mov  ax, @data
  mov  ds, ax

  mov  ax, 0b800h
  mov  es, ax

  mov  ah, 9
  lea  dx, some_text
  int  21h

  call salva_ecran

  mov  ax, 4c00h
  int  21h

salva_ecran proc
        xor     bx,bx
        mov     cx,25*80 * 2  ;◄■■ * 2

salva:          
        mov dl, es:[bx]
        mov consoleText[bx], dl
        inc bx
        cmp bx, cx
        jb salva
        ret
salva_ecran endp