如何在 C 中获得正确的全局变量初始化?
How to get correct global variable initialization in C?
我目前正在编写自定义内核。
我注意到 none 我声明的全局变量被初始化为正确的值。
这是一个例子:
#include <tty.h>
#include <gdt.h>
#include <idt.h>
uint8_t name = 0x45;
void kernel_main() {
terminal_init();
terminal_clear();
terminal_write_string("\nWelcome to los kernel.\n\n");
terminal_write_string("(Kernel info) : TTY Loaded\n");
gdt_reload();
terminal_write_string("(Kernel info) : GDT installed\n");
idt_install();
terminal_write_string("(Kernel info) : IDT installed\n");
terminal_write_hex(name);
}
最后一行应该打印十六进制“0x45”,但我得到“0x0”。
当我尝试从全局字符串数组中获取字符串时,也会发生同样的情况。
这是我的 gcc 编译标志 -ffreestanding -m32 -fno-pie -Wall -Wextra -g -I$(KERNEL_INC_DIR) -masm=intel -std=gnu17
请问我该怎么办?
此致
编辑 1
同样的事情发生在这里:
/* To print the message which defines every exception */
const char* _messages[] = {
"Division By Zero",
"Debug",
"Non Maskable Interrupt",
"Breakpoint",
"Into Detected Overflow",
"Out of Bounds",
"Invalid Opcode",
"No Coprocessor",
"Double Fault",
"Coprocessor Segment Overrun",
"Bad TSS",
"Segment Not Present",
"Stack Fault",
"General Protection Fault",
"Page Fault",
"Unknown Interrupt",
"Coprocessor Fault",
"Alignment Check",
"Machine Check",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved"
};
void isr_handler(ISRStack stack) {
terminal_write_string("Interrupt ");
terminal_write_hex(stack.id);
terminal_write_string(" : ");
terminal_write_string(_messages[stack.id]);
terminal_write_string("\n");
// Hang if it is an exception
if (stack.id < 32) while (1);
}
除非我将 _messages
数组声明放在本地范围内,否则当我用 gdb 检查它时它只会被 0 填充。
如以上评论所述:
您正在使用自己的引导加载程序。在其中指定必须从磁盘加载多少扇区。当您没有加载足够的扇区时,可能只有部分内核是 运行。如果你幸运的话,不会有太多的崩溃(就像你的情况一样),因为 .text 部分被完全复制了。如果你不走运,你会进入一个引导循环。您的确切问题是您没有完全从磁盘加载 .data 部分。祝你开发内核好运 :D
我目前正在编写自定义内核。 我注意到 none 我声明的全局变量被初始化为正确的值。 这是一个例子:
#include <tty.h>
#include <gdt.h>
#include <idt.h>
uint8_t name = 0x45;
void kernel_main() {
terminal_init();
terminal_clear();
terminal_write_string("\nWelcome to los kernel.\n\n");
terminal_write_string("(Kernel info) : TTY Loaded\n");
gdt_reload();
terminal_write_string("(Kernel info) : GDT installed\n");
idt_install();
terminal_write_string("(Kernel info) : IDT installed\n");
terminal_write_hex(name);
}
最后一行应该打印十六进制“0x45”,但我得到“0x0”。 当我尝试从全局字符串数组中获取字符串时,也会发生同样的情况。
这是我的 gcc 编译标志 -ffreestanding -m32 -fno-pie -Wall -Wextra -g -I$(KERNEL_INC_DIR) -masm=intel -std=gnu17
请问我该怎么办? 此致
编辑 1 同样的事情发生在这里:
/* To print the message which defines every exception */
const char* _messages[] = {
"Division By Zero",
"Debug",
"Non Maskable Interrupt",
"Breakpoint",
"Into Detected Overflow",
"Out of Bounds",
"Invalid Opcode",
"No Coprocessor",
"Double Fault",
"Coprocessor Segment Overrun",
"Bad TSS",
"Segment Not Present",
"Stack Fault",
"General Protection Fault",
"Page Fault",
"Unknown Interrupt",
"Coprocessor Fault",
"Alignment Check",
"Machine Check",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved"
};
void isr_handler(ISRStack stack) {
terminal_write_string("Interrupt ");
terminal_write_hex(stack.id);
terminal_write_string(" : ");
terminal_write_string(_messages[stack.id]);
terminal_write_string("\n");
// Hang if it is an exception
if (stack.id < 32) while (1);
}
除非我将 _messages
数组声明放在本地范围内,否则当我用 gdb 检查它时它只会被 0 填充。
如以上评论所述:
您正在使用自己的引导加载程序。在其中指定必须从磁盘加载多少扇区。当您没有加载足够的扇区时,可能只有部分内核是 运行。如果你幸运的话,不会有太多的崩溃(就像你的情况一样),因为 .text 部分被完全复制了。如果你不走运,你会进入一个引导循环。您的确切问题是您没有完全从磁盘加载 .data 部分。祝你开发内核好运 :D