Char * 始终为空终止符

cclgggtu  于 2023-10-16  发布在  其他
关注(0)|答案(1)|浏览(121)

我试图实现一个VGA打印功能,但我不能得到数据被视为一个非空字符。即使我在这个函数中硬编码数据,它仍然会跳过while循环。我有一个调试打印,如果计数为零,它将打印Z,并且它总是打印它,光标不移动,所以我很有信心它没有进入while循环

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++;
    }

    // move the cursor
    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",则可以工作

x6yk4ghg

x6yk4ghg1#

函数中存在问题,但没有一个可以解释观察到的行为。可能是全局变量current_xcurrent_yscreen_x的初始值有问题,或者是你从没有发布的代码中调用函数的方式有问题。VGA_CRT_INDEXVGA_CURSOR_LOWVGA_CRT_DATAVGA_CURSOR_HIGHVGA_MEM_LOC和函数x86_port_out的定义也可能不正确。
以下是一些问题:

  • 所有输出都从VGA屏幕缓冲区的基址开始。
  • current_xcurrent_y会为每个字节和换行符进行更新,但vga指针不会移动,因此下一个字符会粘在上一个输出上。
  • *data == '\n':这将导致无限循环。
  • 你不处理current_y >= screen_y的情况。

以下是修改后的版本:

void vga_print(const char *data, unsigned char mode) {

    uint16_t *vga = (uint16_t *)(VGA_MEM_LOC);
    uint16_t location = current_x + current_y * screen_x;
    uint16_t i;
    uint8_t ch;

    while ((ch = *data++) != '\0') {
        if (ch == '\n' || current_x >= screen_x) {
            current_x = 0;
            current_y++;
            location = current_y * screen_x;
        }
        if (current_y >= screen_y) {
            current_y = screen_y - 1;
            location = current_y * screen_x;
            // shift the screen contents up one line
            for (i = 0; i < location; i++)
                vga[i] = vga[i + screen_x];
            }
            // erase the bottom line
            for (i = 0; i < screen_x; i++) {
                vga[location + i] = ' ' | (mode << 8);
            }
            location += screen_x;
        }
        if (ch != '\n') {
            vga[location++] = ch | (mode << 8);
            current_x++;
        }
    }

    // move the cursor
    x86_port_out(VGA_CRT_INDEX, VGA_CURSOR_LOW);
    x86_port_out(VGA_CRT_DATA, (uint8_t)location);

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

相关问题