You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VGA打印函数无法进入while循环:char*始终为空终止符

VGA打印函数无法进入while循环的问题解决

问题描述

我正在实现一个VGA打印函数,但传入的data始终被识别为空字符,即便在函数内硬编码数据,程序也会跳过while循环。调试时发现每次count都是0(触发打印Z的逻辑),光标也未移动,确认程序完全没进入循环。

代码实现如下:

void vga_print(char *data, char mode) {

    char *vga = (char *)(VGA_MEM_LOC);

    uint8_t count = 0;
    while (*data != '\0') {
        if (*data == '\n') {
            current_x = 0;
            current_y++;
        } else {
            *vga++ = *data++;
            *vga++ = mode;
            current_x++;
            if (current_x >= screen_x) {
                current_x = 0;
                current_y++;
            }
        }
        count++;
    }

    // 移动光标
    uint16_t location = current_x + ((current_y) * screen_x);

    x86_port_out(VGA_CRT_INDEX, VGA_CURSOR_LOW);
    x86_port_out(VGA_CRT_DATA,  location);

    x86_port_out(VGA_CRT_INDEX, VGA_CURSOR_HIGH);
    x86_port_out(VGA_CRT_DATA,  location >> 8);
}

补充信息:将字符串初始化为char example[] = "xyz\0"而非char *example = "xyz\0"时,函数即可正常工作。

问题原因

核心差异在于字符串的存储位置与内存访问权限:

  • 使用char *example = "xyz\0"时,"xyz\0"属于字符串字面量,编译器默认会将其放入只读数据段(.rodata)。在内核开发场景中,如果页表未正确映射该只读段,或者当前运行模式(如早期保护模式/实模式)无法访问这段内存,读取*data时会得到错误值(通常是0),直接导致循环条件不成立。
  • 使用char example[] = "xyz\0"时,字符串字面量会被复制到栈或全局数据段的数组中,这段内存处于可正常访问的区域,因此函数能正确读取到字符串内容。

解决方案

  1. 优先使用数组存储字符串:对于需要打印的字符串,直接用char str[] = "目标内容"的方式定义,确保数据位于可访问的内存区域。
  2. 修复只读段的内存映射:若必须使用字符串字面量,需在内核页表配置中,将.rodata段映射为可读内存,保证CPU能正常读取其中的数据。
  3. 校验指针有效性:调用vga_print前,确认传入的data指针指向的内存已正确初始化且具备访问权限,避免传入未映射或权限错误的地址。

额外代码修复

原代码存在一个潜在bug:当遇到'\n'时,未移动data指针,若后续能进入循环,会导致死循环。需在换行分支中添加指针移动逻辑:

if (*data == '\n') {
    current_x = 0;
    current_y++;
    data++; // 新增该行,避免死循环
}

内容的提问来源于stack exchange,提问作者octalgon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 08:35:59