V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
amiwrong123
V2EX  ›  程序员

汇编实现 屏幕上滚的 原理?

  •  
  •   amiwrong123 · 2023-01-03 21:03:13 +08:00 · 2096 次点击
    这是一个创建于 449 天前的主题,其中的信息可能已经有所发展或是发生改变。

    大概意思就是屏幕上显示字符串,是依靠 显示缓冲区(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处。

    虽然上面这些东西不是书里的重要内容。但还是有几个问题,想问一下:

    1. 我理解 屏幕上滚,就是 屏幕现在只能显示到 字符串的后半段,前半段 屏幕装不下了,所以需要 有回滚操作。对吧?
    2. 为什么上面这个 copy 动作,就可以实现 上滚?
      1. 是屏幕上 始终只显示0x800b8000开始的 n 字节的字符串吗?所以就需要 copy 到这个特定位置。
    3. 这么直接 copy 不会直接 覆盖到别的字符串吗?

    或者说,这个“上滚”我是不是理解反了。屏幕刚开始是 显示的是开始的内容,然后屏幕往上动,然后人就看到了 后面的内容。

    9 条回复    2023-01-05 04:14:35 +08:00
    ruxuan1306
        1
    ruxuan1306  
       2023-01-03 21:17:45 +08:00
    不知道。

    在 DOS 汇编程序中,如果要向屏幕上打印文字,我只用先把要打印的文本缓冲区内存地址填到相应寄存器,再设置系统功能号到相应寄存器,最后 int 调用系统中断将 CPU 控制权交给操作系统,我就完事了。

    我觉得在别的操作系统上应该也类似,我只需将文本存入约定内存区域,再调用操作系统相应功能,最终由操作系统与硬件交互渲染上屏。
    ysc3839
        2
    ysc3839  
       2023-01-03 21:20:02 +08:00 via Android
    “是屏幕上 始终只显示 0x800b8000 开始的 n 字节的字符串吗?”
    是的
    GeruzoniAnsasu
        3
    GeruzoniAnsasu  
       2023-01-03 21:40:05 +08:00   ❤️ 2
    实模式?

    各种微机体系的具体实现天差地别,但有个通用做法是把各种外存全部都映射到同一线性地址空间去,比如 0~0x100 是 BIOS ,0x1000~0x2000 是显存之类的。

    x86 的显卡,字符模式可以直接把字符拷贝到显存里自动渲染出来,我猜你这里就是这么回事,这段地址被映射成显存了。
    clearbug
        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
    levelworm
        5
    levelworm  
       2023-01-04 04:51:52 +08:00
    我就特别喜欢这种问题。把楼上几位回答的都加入特别关注了。
    oott123
        6
    oott123  
       2023-01-04 09:04:30 +08:00 via Android
    这个“上滚”你是理解反了。屏幕刚开始是 显示的是开始的内容,然后屏幕往上动,然后人就看到了 后面的内容。
    mepwang
        7
    mepwang  
       2023-01-04 11:52:26 +08:00
    这里显示是把一块内存区域映射为屏幕上显示的内容
    上滚的意思是屏幕显示满了,到了最下面一行,屏幕上的行会向上移动,最上面一行消失,
    最下面新增一行。
    所以滚屏实际上的实现是内存块的移动
    需要移动的内存大小就是屏幕大小,80 列×24 行=1920 个字节
    mepwang
        8
    mepwang  
       2023-01-04 11:54:25 +08:00
    错了是 1920 个字符,不是字节
    ericFork
        9
    ericFork  
       2023-01-05 04:14:35 +08:00
    难得看到汇编的问题,不知道还有没有人记得文曲星上的「批量法」
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3945 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 38ms · UTC 10:24 · PVG 18:24 · LAX 03:24 · JFK 06:24
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.