Nor*_*sey 22
这是一个带有缩写的场景:
printf
或者cout
将字符放入用户程序地址空间的缓冲区中.printf
要求提前清空缓冲区.无论哪种方式,I/O库都会调用操作系统,该操作系统会将缓冲区的内容复制到自己的空间.令人惊讶的是,熊在跳舞.
vla*_*adr 19
那么基本上这些功能是如何制作的?它是汇编吗?如果是的话,它从哪里开始?这带来了更多的问题,例如他们如何制作openGl/directx函数.
这些功能可以是汇编或C,它不会有太大变化(无论如何,你可以在C中做几乎任何你可以在汇编中做的事情.) 魔术最终发生在软件和硬件的界面 - 你如何到达那里来自printf
并且cout <<
可以像几个指针操作一样简单(参见下面的286示例,或者cprintf
进一步了解),或者在最终点击显示硬件之前,通过多层系统调用,甚至可能通过网络进行复杂.
想象一下以下场景:
我从尘土中挖出旧的286并点燃了MS-DOS; 我在实模式下编译并运行以下程序:
void main(void) {
far long* pTextBuf = (far long*)0xb8000L;
/* Poor man's gotoxy+cprintf imitation -- display "C:" (0x43,0x3a) in
silver-on-black letters in the top-left corner of the screen */
*pTextBuf = 0x073a0743L;
}
Run Code Online (Sandbox Code Playgroud)我将笔记本电脑的Windows HyperTerminal连接到我的串口,该端口连接着一个SUN盒背面的电缆,通过它我可以访问我的SUN盒控制台.从那个控制台我ssh到网络上的另一个盒子,在那里我运行我的程序printf
,管道输出通过more
.该printf
信息已经通过管道通过旅行more
通过网络,通过串行电缆终于出现在我的屏幕上之前,然后通过SSH伪终端,以我的太阳箱,从那里到我的笔记本电脑,通过Windows的GDI文本绘图函数.
为诺曼的答案添加更多细节,希望更多地朝着原始问题的方向发展:
printf
并且cout <<
通常执行写入stdout
- 通常是缓冲写入,但情况并非总是如此
cprintf
,它直接写入视频内存而不进行任何系统调用,memcpy
-style(参见我上面的286示例) - 更多内容再向下stdout
是一个系统调用,无论是write
在*nix下,WriteFile
还是WriteConsole
在Windows下,在UNIX 下的INT 21,9等等.stdout
抽象的优点是它允许操作系统做一些内部管道并执行重定向(无论是tty描述符,管道,文件,串行端口,通过套接字等到另一台机器等.)
stdout
在同一屏幕上共存成为可能,例如在不同的窗口中 - 如果每个应用程序都试图直接写入视频内存(就像cprintf
在DOS上那样),那就更难了- 不是今天所谓的真正的或可用的多任务操作系统.)rxvt
将:
stdout
:
rxvt
Windows控制台的情况下cprintf
实现还是OS)写入更小的80x25或80x50等文本缓冲器阵列,其中(例如在VGA的情况下)只需要两个字节来编码每个字符值例如A
或?
或?
(1字节)以及它的颜色属性(1字节) - 即它的前景(4位,或3位+亮度位)和背景颜色(4位,或3位+闪烁位)从Wikipedia上的视频卡和GPU页面历史开始,更深入地了解我们今天的状态.