将控制台遮阳板内容保存到数组中(程序集)
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
我正在学校开始学习一门新语言(汇编),我需要为此做一些工作 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