这段代码如何显示到屏幕上?
How does this code to display to screen works?
当我找到真正的 OS 开发教程时,我正在浏览整个 Internet 上的内核开发教程。
我查看了代码,但我无法理解这一点。
代码如下:
int main(void){
char *str = "Hello, world", *ch;
unsigned short *vidmem = (unsigned short*) 0xb8000;
unsigned i;
for (ch = str, i = 0; *ch; ch++, i++)
vidmem[i] = (unsigned char) *ch | 0x0700;
for (;;);
}
当我使用 Dev C++ 编译上述代码并生成 Win32 控制台或 Windows 应用程序时,当我 运行 它时它崩溃了,它告诉我我的程序 "has stopped working" 和终止。它似乎在循环中的这一行失败:
vidmem[i] = (unsigned char) *ch | 0x0700;
代码有什么问题,我该如何解决?
在for循环中:
for (ch = str, i = 0; *ch; ch++, i++)
vidmem[i] = (unsigned char) *ch | 0x0700;
条件部分 *ch
指示 C 编译器在表达式为 true(非零)时继续循环.只要 *ch
不是 NUL(\0) 终止符,表达式就会 true 并继续循环。当它到达一个为零的字符时,条件表达式将为 false 并且循环退出。它有效地循环遍历一个字符串,直到它到达 NUL 终止字符。
vidmem[i] = (unsigned char) *ch | 0x0700;
崩溃的原因是因为 vidmem
被赋予了显存地址 0xb8000。基于 Win32 的应用程序无法访问此内存,OS (Windows) 将使您的应用程序出错并显示有关程序不再工作的错误消息。
解决这个问题的唯一方法是以可以用作 MS-DOS 程序的方式编译它:
- 使用 16 位 C 编译器和 运行 在 MS-DOS 或像 DosBox
这样的 MS-DOS 模拟器中编译
- 将其编译到您的内核中并在裸机环境(QEMU、Virtualbox、VMWare 等)中进行测试
*ch | 0x0700
获取当前字符并将其按位或运算为 0x0700。这有效地创建了一个 16 位字,字符在低 8 位,0x07 在高 8 位。
这样做是因为您在使用内存区域 0xb8000 的标准彩色文本视频模式中看到的每个字符都由 2 个字节(一个 16 位字)组成。这在 Wikipedia article:
中描述
如果循环中正在处理的当前字符是字母 H (0x48) 那么 *ch | 0x0700
将变为 0x0748 然后存储在特定的内存位置视频显示。
您可能希望阅读 C 中的位操作。我发现这个 tutorial 可能有帮助。
当我找到真正的 OS 开发教程时,我正在浏览整个 Internet 上的内核开发教程。
我查看了代码,但我无法理解这一点。
代码如下:
int main(void){
char *str = "Hello, world", *ch;
unsigned short *vidmem = (unsigned short*) 0xb8000;
unsigned i;
for (ch = str, i = 0; *ch; ch++, i++)
vidmem[i] = (unsigned char) *ch | 0x0700;
for (;;);
}
当我使用 Dev C++ 编译上述代码并生成 Win32 控制台或 Windows 应用程序时,当我 运行 它时它崩溃了,它告诉我我的程序 "has stopped working" 和终止。它似乎在循环中的这一行失败:
vidmem[i] = (unsigned char) *ch | 0x0700;
代码有什么问题,我该如何解决?
在for循环中:
for (ch = str, i = 0; *ch; ch++, i++)
vidmem[i] = (unsigned char) *ch | 0x0700;
条件部分 *ch
指示 C 编译器在表达式为 true(非零)时继续循环.只要 *ch
不是 NUL(\0) 终止符,表达式就会 true 并继续循环。当它到达一个为零的字符时,条件表达式将为 false 并且循环退出。它有效地循环遍历一个字符串,直到它到达 NUL 终止字符。
vidmem[i] = (unsigned char) *ch | 0x0700;
崩溃的原因是因为 vidmem
被赋予了显存地址 0xb8000。基于 Win32 的应用程序无法访问此内存,OS (Windows) 将使您的应用程序出错并显示有关程序不再工作的错误消息。
解决这个问题的唯一方法是以可以用作 MS-DOS 程序的方式编译它:
- 使用 16 位 C 编译器和 运行 在 MS-DOS 或像 DosBox 这样的 MS-DOS 模拟器中编译
- 将其编译到您的内核中并在裸机环境(QEMU、Virtualbox、VMWare 等)中进行测试
*ch | 0x0700
获取当前字符并将其按位或运算为 0x0700。这有效地创建了一个 16 位字,字符在低 8 位,0x07 在高 8 位。
这样做是因为您在使用内存区域 0xb8000 的标准彩色文本视频模式中看到的每个字符都由 2 个字节(一个 16 位字)组成。这在 Wikipedia article:
中描述如果循环中正在处理的当前字符是字母 H (0x48) 那么 *ch | 0x0700
将变为 0x0748 然后存储在特定的内存位置视频显示。
您可能希望阅读 C 中的位操作。我发现这个 tutorial 可能有帮助。