简体   繁体   English

全局变量始终初始化为零

[英]global variable always initialized zero

I've been writing an OS using this tutorial. 我一直在使用教程编写操作系统。 I am at the part where the boot loader is completed and C is used for programming (and then linked together ...). 我在启动加载程序完成的部分,C用于编程(然后链接在一起......)。 But that just as a note, I believe the problem I have is related to gcc. 但这只是一个注释,我相信我遇到的问题与gcc有关。

I build an i386-elf cross compiler for the OS. 我为操作系统构建了一个i386-elf交叉编译器。 And everything works fine, I can execute my code everything works. 一切正常,我可以执行我的代码一切正常。 Except that all global variables are initialized zero, although I provided a default value . 除了所有全局变量都初始化为零之外, 尽管我提供了一个默认值

int test_var = 1234;

// yes, void main() is correct (the boot-loader will call this)
void main() {} 

If I debug this code with GDB, I get: ( gcc-7.1.0, target: i328-elf ) 如果我使用GDB调试此代码,我得到:( gcc-7.1.0, target: i328-elf

(gdb) b main
Breakpoint 1 at 0x1554: file src/kernel/main.c, line 11.
(gdb) c
Continuing.

Breakpoint 1, main () at src/kernel/main.c:11
11  void main() {
(gdb) p test_var
$1 = 0

If i run the same code on my local machine ( gcc-6.3.0, target: x86_64 ), it prints 1234 . 如果我在本地计算机上运行相同的代码( gcc-6.3.0, target: x86_64 ),则会打印1234

My question is: Did I misconfigure gcc, is this a mistake in my OS, is this a known problem? 我的问题是:我是否错误配置了gcc,这是我操作系统中的错误,这是一个已知问题吗? I couldn't find anything about it. 我找不到任何关于它的东西。

My entire source-code: link I use the following commands to compile my stuff: 我的整个源代码: 链接我使用以下命令编译我的东西:

# ...
i386-elf-gcc -g -ffreestanding -Iinclude/ -c src/kernel/main.c -o out/kernel/main.o
# ...
i386-elf-ld -e 0x1000 -Ttext 0x1000 -o out/kernel.elf out/kernel_entry.o out/kernel/main.o # some other stuff ...
i386-elf-objcopy -O binary out/kernel.elf out/kernel.bin
cat out/boot.bin out/kernel.bin > out/os.bin
qemu-system-i386 -drive "format=raw,file=out/os.bin"

EDIT: As @EugeneSh. 编辑:作为@EugeneSh。 suggested here some logic to make sure, that it's not removed: 这里建议一些逻辑来确保它没有被删除:

#include <cpu/types.h>
#include <cpu/isr.h>

#include <kernel/print.h>

#include <driver/vga.h>

int test_var = 1234;

void main() {
  vga_text_init();

  switch (test_var) {
    case 1234: print("That's correct"); break;
    case 0: print("It's zero"); break;

    // I don't have a method like atoi() in place, I would use
    // GDB to get the value
    default: print("It's something else");
  }
}

Sadly it prints It's zero 可悲的是它打印It's zero

Compiler never clears uninitialized global variables to zero, its logic in built inside loader, So when you allocate memory for data segment then it size contains bss section also. 编译器永远不会将未初始化的全局变量清除为零,它在内置加载器中的逻辑,所以当你为数据段分配内存时,它的大小也包含bss部分。 So you have to check bss section offset, alignment & size withing data segment and memset() them to '0'. 所以你必须检查bss部分偏移,对齐和大小与数据段和memset()它们为'0'。

As you are writing your OS so may be all the library routines are not available so better write memset() function using assembly. 在编写操作系统时,可能所有库例程都不可用,因此使用汇编更好地编写memset()函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM