Winapi 此代码如何显示到屏幕上?

Winapi 此代码如何显示到屏幕上?,winapi,gcc,x86,kernel,osdev,Winapi,Gcc,X86,Kernel,Osdev,当我在互联网上浏览内核开发教程时,发现了真正的操作系统开发教程 我通读了代码,但我不明白这一点 代码如下: 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 | 0x07

当我在互联网上浏览内核开发教程时,发现了真正的操作系统开发教程

我通读了代码,但我不明白这一点

代码如下:

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 (;;);
}
当我使用DEVC++来编译上面的代码并生成Win32控制台或Windows应用程序时,当我运行它时,它崩溃了,它告诉我程序已经停止工作并终止。它似乎在循环中的这一行失败:

vidmem[i] = (unsigned char) *ch | 0x0700;
代码有什么问题,如何解决问题?

在for循环中:

for (ch = str, i = 0; *ch; ch++, i++)
    vidmem[i] = (unsigned char) *ch | 0x0700;
条件部分*构造C编译器,使其在表达式为非零的情况下继续循环。只要*ch不是NUL\0终止字符,表达式将为true并将继续循环。当它到达零字符时,条件表达式将为false,循环将退出。实际上,它在字符串中循环,直到到达NUL终止字符

使用vidmem[i]=未签名字符*ch | 0x0700崩溃的原因;是因为vidmem获得了视频内存地址0xb8000。基于Win32的应用程序无法访问此内存,操作系统Windows将为您的应用程序设置故障,并显示有关程序不再工作的错误消息

解决此问题的唯一方法是将其编译为可以用作MS-DOS程序的方式:

使用16位C编译器编译并在MS-DOS或类似DosBox的MS-DOS仿真器中运行 将其编译到内核中,并在裸机环境QEMU、Virtualbox、VMWare等中进行测试。 *ch | 0x0700获取当前字符并按位将其OR为0x0700。这将有效地创建一个16位字,其中字符位于下8位,0x07位于上8位

之所以这样做,是因为在使用内存区域0xb8000的标准彩色文本视频模式中看到的每个字符都由2个字节和一个16位字组成。这在以下章节中描述:

如果循环中正在处理的当前字符是字母H 0x48,则*ch | 0x0700将变为0x0748,然后存储在视频显示器上的特定内存位置


您可能希望阅读C中的位操作。我发现这可能会有所帮助。

它表明for语句中的错误不是问题描述。有两个for语句-哪一个是导致错误的原因?它显示的确切错误是什么?你在屏幕上的信息就在你面前;你完全没有理由不把它包括在你的问题中,所以我们也有它。我直接在windows上运行这个程序。因此,将有任何问题,如访问0xB8000的非法内存内存保护。windows是否允许访问?不,windows程序不支持此操作。Win32应用程序无法直接访问视频内存。在更新vidmem时,可能会导致程序出现故障/崩溃。你真正的问题是——为什么我的Win32程序在运行时会崩溃?此代码用于裸机环境或MS-DOS环境。如果使用针对DOS的TurboC或Microsoft-C编译器进行编译并在DOS环境或DosBoxSo之类的仿真器中运行,则此代码可以工作。因此,我必须编译代码并创建引导加载程序来加载文件,以便查看输出。对吗?除了找到一个20多年前的16位C编译器,如果你在64位Windows系统上,在Dosbox中运行可执行文件之外,没有真正简单的方法。在内核中测试它可能是最好的。有一个按位或分隔字符和属性的方法,为什么?@PantherCoder我已经更新了我的答案一点来触及这一点,还有一个指向Cvidmem[0]中位操作教程的链接,指向0xB800。由于它是受保护模式代码,它将在其中存储8位还是16位?@PantherCoder vidmem它被定义为一个无符号short*,其作用类似于指向无符号short int数组的指针。因此,vidmem[i]=将每个元素视为无符号短整数。编译器中的无符号短整数是2字节宽的16位整数,因此它将在每次赋值时存储2字节