汇编实现 屏幕上滚的 原理? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
amiwrong123

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

  •  
  •   amiwrong123 2023 年 1 月 3 日 2940 次点击
    这是一个创建于 1207 天前的主题,其中的信息可能已经有所发展或是发生改变。

    大概意思就是屏幕上显示字符串,是依靠 显示缓冲区(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 年 1 月 3 日
    不知道。

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

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

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

    x86 的显卡,字符模式可以直接把字符拷贝到显存里自动渲染出来,我猜你这里就是这么回事,这段地址被映射成显存了。
    clearbug
        4
    clearbug  
       2023 年 1 月 3 日   3
    1. 屏幕上可以显示 25 行 80 列的字符,假设你有 26 行的文本要输出到屏幕上,那么在输出第 26 行时,屏幕上面已经显示了已有的 25 行的字符,这个时候就需要滚屏,把屏幕上 2-25 行的字符复制到 1-24 行,总共需要复制 24 行,并把屏幕上第 25 行清空(显示空格字符即清空),这样屏幕上的第 25 行就可以用来显示文本的第 26 行的内容了。
    2. 屏幕上一个字符占用两个字节(字符本身占一个字节、字符的颜色占用一个字节),1920 = 24 * 80
    levelworm
        5
    levelworm  
       2023 年 1 月 4 日
    我就特别喜欢这种问题。把楼上几位回答的都加入特别关注了。
    oott123
        6
    oott123  
       2023 年 1 月 4 日 via Android
    这个“上滚”你是理解反了。屏幕刚开始是 显示的是开始的内容,然后屏幕往上动,然后人就看到了 后面的内容。
    mepwang
        7
    mepwang  
       2023 年 1 月 4 日
    这里显示是把一块内存区域映射为屏幕上显示的内容
    上滚的意思是屏幕显示满了,到了最下面一行,屏幕上的行会向上移动,最上面一行消失,
    最下面新增一行。
    所以滚屏实际上的实现是内存块的移动
    需要移动的内存大小就是屏幕大小,80 列×24 行=1920 个字节
    mepwang
        8
    mepwang  
       2023 年 1 月 4 日
    错了是 1920 个字符,不是字节
    ericFork
        9
    ericFork  
       2023 年 1 月 5 日
    难得看到汇编的问题,不知道还有没有人记得文曲星上的「批量法」
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     901 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 41ms UTC 19:48 PVG 03:48 LAX 12:48 JFK 15:48
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86