此外,标准输出就是这样。“屏幕”的概念是操作系统的抽象。例如,在 Linux 和其他一些 UNIX 中,您的进程与 TTY 或 PTY(电传打字机和伪电传打字机)相关联,这是 stdout 可以指向的地方,但不是必须的。Stdout 可以指向一个文件,一个网络,任何东西!你必须区分真正的终端(想想 Ubuntu 上的 Ctrl-Alt-F1)和伪终端(想想 Konsole、CMD、Terminal.app)。当您有一个伪终端时,它位于一个窗口中,这会使事情复杂 10 倍。如果你有一个伪终端,这里可能是步骤(Linux):
- 进行系统调用 (
write
) 以将字符串写入 FD 0。
write
将写入与 FD 0 关联的文件,该文件很可能附加到您的 PTY 的从控制器。然后,终端仿真器(主控制器)接收输出。
- 它使用某种图形库(GTK、Qt、SDL、OpenGL 等)来渲染到它的窗口缓冲区。这就是字体幻想会发生的地方。
- 窗口缓冲区被传递给窗口管理器和 X 窗口系统,它们与所有其他窗口和事物一起绘制它。
至于视频驱动,这个系统的两个部分都用到了视频驱动:X windows和OpenGL。视频驱动程序由配置文件和硬件发现设置,其中操作系统(或 BIOS)探测系统以查找所有可用硬件并加载驱动程序。
CPU如何将数据放入总线?(据我所知,以下是特定于 x86 和 Linux 的)。好吧,数据必须以某种方式到达显卡。它可以通过几种方式发生。视频卡将一些视频内存映射到 CPU 内存,或者您使用 x86 I/O 端口(in
和out
指令)。
让我们看第一种情况。所有视频卡都在段地址 0xb800 处映射一个文本视频缓冲区(有些还在某处映射某种 3d 数据缓冲区,但我不确定)。因此,如果我想将字符串写入"Hello, world"
视频缓冲区,这里有一些 x86 ASM:
mov es, B800H ;Set the extra segment to the video buffer
mov ds, cs ;Set the data segment
mov esi, hellomsg ;Set the source index to the hellomsg
mov edi, 0 ;Video buffer offset
mov ecx, [hellolen] ;How many characters
rep movsb ;Copy
;;Data
hellomsg db "Hello, world!" ;Null terminated hello world
hellolen dw 13
顺便说一句,这是驱动程序或操作系统级别的 ASM——它需要直接访问视频缓冲区,或者至少需要将视频缓冲区映射到您的地址空间。另一个选项,I/O 端口,是驱动程序参与的地方。因为什么端口和写什么取决于显卡,我不会举例,但你可以看看。