当我找到真正的操作系统开发教程时,我正在浏览整个互联网上的内核开发教程。
我查看了代码,但我无法理解。
代码如下:
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应用程序时,它在运行时崩溃,它告诉我我的程序“已停止工作”并终止。它似乎在循环中的这一行失败:
vidmem[i] = (unsigned char) *ch | 0x0700;
代码有什么问题,我该如何解决问题?
答案 0 :(得分:2)
在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的应用程序无法访问此内存,操作系统(Windows)将使您的应用程序出现故障并显示有关该程序不再有效的错误消息。
解决此问题的唯一方法是以可以用作MS-DOS程序的方式编译它:
*ch | 0x0700
获取当前字符并按位或将其设置为0x0700。这有效地创建了一个16位字,其中字符位于低8位,0x07位于高8位。
这样做是因为在使用内存区域0xb8000的标准彩色文本视频模式下看到的每个字符都由2个字节(一个16位字)组成。这在Wikipedia article:
中有所描述如果循环中处理的当前字符是字母 H (0x48),那么*ch | 0x0700
将变为0x0748,然后存储在视频显示器上的特定存储位置。< / p>
您可能希望阅读 C 中的位操作。我发现这个tutorial可能会有所帮助。