简单的C内核字符指针不起作用

Hop*_*Abc 4 c x86 pointers kernel osdev

我正在尝试使用C创建一个简单的内核.一切都加载并正常工作,我可以访问视频内存并显示字符,但是当我尝试实现一个简单的put函数由于某种原因它不起作用.我已经尝试了自己的代码和其他代码.此外,当我尝试使用在函数外声明的变量时,它似乎不起作用.这是我自己的代码:

#define PUTCH(C, X) pos = putc(C, X, pos)
#define PUTSTR(C, X) pos = puts(C, X, pos)

int putc(char c, char color, int spos) {
    volatile char *vidmem = (volatile char*)(0xB8000);
    if (c == '\n') {
        spos += (160-(spos % 160));
    } else {
        vidmem[spos] = c;
        vidmem[spos+1] = color;
        spos += 2;
    }
    return spos;
}
int puts(char* str, char color, int spos) {
    while (*str != '\0') {
        spos = putc(*str, color, spos);
        str++;
    }
    return spos;
}
int kmain(void) {
    int pos = 0;
    PUTSTR("Hello, world!", 6);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

spos(起始位置)的东西,因为我不能让全球定位变量.putc工作正常,但puts没有.我也试过这个:

unsigned int k_printf(char *message, unsigned int line) // the message and then the line #
{
    char *vidmem = (char *) 0xb8000;
    unsigned int i=0;

    i=(line*80*2);

    while(*message!=0)
    {
        if(*message=='\n') // check for a new line
        {
            line++;
            i=(line*80*2);
            *message++;
        } else {
            vidmem[i]=*message;
            *message++;
            i++;
            vidmem[i]=7;
            i++;
        };
    };

    return(1);
};

int kmain(void) {
    k_printf("Hello, world!", 0);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

为什么这不起作用?我尝试将put实现与我的原生GCC(没有颜色和spos数据和使用printf("%c"))一起使用,并且它工作正常.

Jas*_*son 6

由于您通常遇到全局变量问题,因此问题很可能与链接器将"Hello World"字符串文字放在内存中的位置有关.这是因为字符串文字通常由链接器存储在全局内存的只读部分中......您还没有详细说明如何编译和链接内核,所以我会尝试类似下面的内容看看是否有效:

int kmain(void) 
{
    char array[] = "Hello World\n";
    int pos = 0;
    puts(array, 0, pos);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这将在堆栈上分配字符数组而不是全局内存,并避免链接器决定放置全局变量的任何问题.

通常,在创建简单内核时,您希望将其编译并链接为平面二进制文件,而不依赖于外部OS库.如果您正在使用像GRUB这样的多引导兼容引导加载程序,您可能需要查看多引导规范页面中的简单示例代码.

  • `char array [] ="Hello,World \n";`应该给你完全相同的行为. (2认同)