C语言编写内核时无法写入字符数组的问题求助
问题分析与修复方案
首先,你的代码里最致命的错误出在print函数的循环逻辑中——你在循环里对字符指针chr进行了两次递增操作,导致指针移动过快,直接跳过字符,甚至可能跳过字符串的终止符'\0',进入未初始化内存区域;如果该区域恰好以0开头,就会表现为字符串长度被识别为0,什么都不打印。
具体错误点
看你的print函数代码:
void print(char* msg, unsigned int line, enum vga_color back, enum vga_color fore) { unsigned char* vidmem = (unsigned char*) VGA_ADDR; unsigned int i = (line*80*2); for (char* chr = msg; *chr != '\0'; chr++) { vidmem[i] = *chr; vidmem[i+1] = hex_combine(back, fore); chr++; // 这里多了一次不必要的递增! i+=2; }; };
在for循环中,每次迭代已经会执行chr++(循环的增量部分),而你在循环体里又额外加了一次chr++。这意味着每处理一个字符,指针就会向前跳两个位置:比如处理完第一个字符'U'后,指针直接从'U'跳到'g',跳过了'n',很快就会超出字符串的有效范围,甚至可能直接指向内存中的0字节,导致循环提前终止,看起来就像字符串长度为0。
修复方法
只需要删除循环体中的chr++;语句,让for循环的增量部分来负责指针的移动:
void print(char* msg, unsigned int line, enum vga_color back, enum vga_color fore) { unsigned char* vidmem = (unsigned char*) VGA_ADDR; unsigned int i = (line*80*2); for (char* chr = msg; *chr != '\0'; chr++) { vidmem[i] = *chr; vidmem[i+1] = hex_combine(back, fore); // 移除多余的chr++ i+=2; }; };
额外检查项
除了这个核心错误,你还可以检查以下几点确保内核正常工作:
- 确认内核编译链接时,字符串常量被正确放入数据段,并且通过引导加载器正确加载到内存中。你的编译脚本用
objcopy将ELF转为binary,这一步通常没问题,但可以通过反汇编确认字符串是否存在于kernel.bin中。 - 检查
hex_combine函数的返回值是否正确:VGA文本模式的属性字节是高4位背景色、低4位前景色,你的(x<<4)|(y)逻辑完全符合要求。 - 引导加载器中的内存分页和模式切换是否正确:你已经切换到64位模式,页表设置是直接映射物理内存,
VGA_ADDR(0xB8000)的映射是正常的,这部分无需调整。
修复后重新编译运行,你的"Unga Bunga"字符串应该就能正常显示在屏幕上了。
内容的提问来源于stack exchange,提问作者Insert joke here
相关产品推荐
相关产品推荐

