不显示字符串(osdev)

问题描述 投票:0回答:1

我目前正在开发一个用于教育目的的小型操作系统(因为这很有趣)。我成功地通过了 64 位模式,并跳转到 C 函数“kmain”以使用更高级别的语言进行编程。一切都已设置完毕(交叉编译器、磁盘读取以将我的 c 函数加载到地址 0x7e00 处的第二个扇区...)。以下代码完美运行:

#define VIDEO_MEMORY_LOCATION 0xb8000

void kmain() {

    char msg[] = "Hello world!";
    int i =0;
    char *video_memory = (char *)VIDEO_MEMORY_LOCATION;

    while (msg[i]) {
        *video_memory = msg[i];
        i++;
        video_memory += 2;
    }
}

我的字符串正确显示。但是,我试图在rodata 中放置一个字符串,如下所示:

#define VIDEO_MEMORY_LOCATION 0xb8000

void kmain() {

    char *msg = "Hello world!";
    char *video_memory = (char *)VIDEO_MEMORY_LOCATION;

    while (*msg) {
        *video_memory = *msg;
        msg++;
        video_memory += 2;
    }
}

而且它不起作用。更准确地说,我的屏幕与以前相同,但未显示字符串。它也不会崩溃。只是字符串不在这里。我的第一个想法是:“.rodata 加载不正确,因此我的字符串不在我的可执行文件中”,但我确信这不是这个,原因如下: 当我拆开时:

00000200  55                push rbp
00000201  4889E5            mov rbp,rsp
00000204  48C745F845FE0000  mov qword [rbp-0x8],0xfe45
0000020C  48C745F000800B00  mov qword [rbp-0x10],0xb8000
00000214  EB17              jmp short 0x22d
00000216  488B45F8          mov rax,[rbp-0x8]
0000021A  0FB610            movzx edx,byte [rax]
0000021D  488B45F0          mov rax,[rbp-0x10]
00000221  8810              mov [rax],dl
00000223  488345F801        add qword [rbp-0x8],byte +0x1
00000228  488345F002        add qword [rbp-0x10],byte +0x2
0000022D  488B45F8          mov rax,[rbp-0x8]
00000231  0FB600            movzx eax,byte [rax]
00000234  84C0              test al,al
00000236  75DE              jnz 0x216
00000238  90                nop
00000239  90                nop
0000023A  5D                pop rbp
0000023B  C3                ret
0000023C  0F1F4000          nop dword [rax+0x0]
00000240  E8BBFFFFFF        call 0x200
00000245  48                rex.w                           # not code, my "Hello world!" string located at 0xfe45
00000246  656C              gs insb
00000248  6C                insb
00000249  6F                outsd
0000024A  20776F            and [rdi+0x6f],dh
...

我们希望看到我的字符串在这里,并且当我们得到字符串时的地址是正确的。 我不明白为什么“你好世界!”不显示。

在 qemu 中,当我显示地址 0xfe45 处的内存内容时,我得到: (qemu)x/8c 0x7e45 000000000007e45:'H''e''l''l''o'''''w''o''r''l''d''!' 'x00'

这种代码:

void kmain() {

    char *video_memory = (char *)VIDEO_MEMORY_LOCATION;
    char msg0[] = "AZE";
    int i = 0;

    while (msg0[i]) {
        *video_memory = msg0[i];
        i++;
        video_memory += 2;
    }

    char *msg = "Hello world!";

    while (*msg) {
        *video_memory = *msg;
        msg++;
        video_memory += 2;
    }
}

仅显示“AZE”。

c assembly operating-system x86-64
1个回答
0
投票

它不起作用。

两个循环之间绝对没有区别

我怀疑您没有像重新定位堆栈一样重新定位

.rodata
,因此从
.rodata
读取失败。

© www.soinside.com 2019 - 2024. All rights reserved.