大概意思就是屏幕上显示字符串,是依靠 显示缓冲区(0x800b_8000
,实际的物理地址为0x000b_8000
)的。
.roll_screen:
cmp bx,2000 ;光标超出屏幕?滚屏
jl .set_cursor
cld
mov esi,0x800b80a0 ;小心! 32 位模式下 movsb/w/d
mov edi,0x800b8000 ;使用的是 esi/edi/ecx
mov ecx,1920
rep movsd
mov bx,3840 ;清除屏幕最底一行
mov ecx,80 ;32 位程序应该使用 ECX
如上图,为实现屏幕上滚的汇编。其实就是把0x800b_80a0
处的东西,复制到0x800b_8000
处。
虽然上面这些东西不是书里的重要内容。但还是有几个问题,想问一下:
0x800b8000
开始的 n 字节的字符串吗?所以就需要 copy 到这个特定位置。或者说,这个“上滚”我是不是理解反了。屏幕刚开始是 显示的是开始的内容,然后屏幕往上动,然后人就看到了 后面的内容。
1
ruxuan1306 2023-01-03 21:17:45 +08:00
不知道。
在 DOS 汇编程序中,如果要向屏幕上打印文字,我只用先把要打印的文本缓冲区内存地址填到相应寄存器,再设置系统功能号到相应寄存器,最后 int 调用系统中断将 CPU 控制权交给操作系统,我就完事了。 我觉得在别的操作系统上应该也类似,我只需将文本存入约定内存区域,再调用操作系统相应功能,最终由操作系统与硬件交互渲染上屏。 |
2
ysc3839 2023-01-03 21:20:02 +08:00 via Android
“是屏幕上 始终只显示 0x800b8000 开始的 n 字节的字符串吗?”
是的 |
3
GeruzoniAnsasu 2023-01-03 21:40:05 +08:00 2
实模式?
各种微机体系的具体实现天差地别,但有个通用做法是把各种外存全部都映射到同一线性地址空间去,比如 0~0x100 是 BIOS ,0x1000~0x2000 是显存之类的。 x86 的显卡,字符模式可以直接把字符拷贝到显存里自动渲染出来,我猜你这里就是这么回事,这段地址被映射成显存了。 |
4
clearbug 2023-01-03 21:46:18 +08:00 3
1. 屏幕上可以显示 25 行 80 列的字符,假设你有 26 行的文本要输出到屏幕上,那么在输出第 26 行时,屏幕上面已经显示了已有的 25 行的字符,这个时候就需要滚屏,把屏幕上 2-25 行的字符复制到 1-24 行,总共需要复制 24 行,并把屏幕上第 25 行清空(显示空格字符即清空),这样屏幕上的第 25 行就可以用来显示文本的第 26 行的内容了。
2. 屏幕上一个字符占用两个字节(字符本身占一个字节、字符的颜色占用一个字节),1920 = 24 * 80 |
5
levelworm 2023-01-04 04:51:52 +08:00
我就特别喜欢这种问题。把楼上几位回答的都加入特别关注了。
|
6
oott123 2023-01-04 09:04:30 +08:00 via Android
这个“上滚”你是理解反了。屏幕刚开始是 显示的是开始的内容,然后屏幕往上动,然后人就看到了 后面的内容。
|
7
mepwang 2023-01-04 11:52:26 +08:00
这里显示是把一块内存区域映射为屏幕上显示的内容
上滚的意思是屏幕显示满了,到了最下面一行,屏幕上的行会向上移动,最上面一行消失, 最下面新增一行。 所以滚屏实际上的实现是内存块的移动 需要移动的内存大小就是屏幕大小,80 列×24 行=1920 个字节 |
8
mepwang 2023-01-04 11:54:25 +08:00
错了是 1920 个字符,不是字节
|
9
ericFork 2023-01-05 04:14:35 +08:00
难得看到汇编的问题,不知道还有没有人记得文曲星上的「批量法」
|