【问题标题】:Can't use global variables with gccgcc 不能使用全局变量
【发布时间】:2019-06-03 16:06:48
【问题描述】:

我有一个这样的文件:

char* vidmem = (char*)0xb8000;

int main()
{
    vidmem[0] = 'x';
    vidmem[1] = 0x0f;
}

但是当我用 gcc 编译它时,它的行为就像 vidmem 甚至不存在一样。我在函数之外声明的所有变量都有这个问题。也许这个可以在 main 中声明,但其他文件中的其他变量则不能。 这就是我编译它的方式:

gcc -c main.c -o main.obj -ffreestanding -fno-exceptions -m64

这就是我组装所有文件的方式:

gcc -m64 -Wl,--build-id=none -static -fno-asynchronous-unwind-tables -nostdlib -nodefaultlibs -lgcc main.obj [..] -T linker.ld -o out.bin

为什么会这样?我该如何解决?

编辑:

我正在制作一个操作系统,这是来自 C 内核的代码。我正在使用 linux 子系统 for windows 来编译它和 qemu 进行测试

这里是所有代码的链接:http://www.mediafire.com/file/7x21lh4dnc93dz9/OS.7z/file

【问题讨论】:

  • “它的行为就像 vidmem 甚至不存在”怎么会?您看到的具体行为是什么?
  • volatile char* vidmem = (char*)0xb8000; 怎么样? BTW,你的平台是什么?看起来您正在将其编译为裸机
  • @Mimmo 我希望屏幕左上角会打印一个“x” 为什么会这样?这是一个非常依赖于平台的期望,而您完全忽略了它。
  • 您是否在 8086 PC 上运行 MS-DOS?
  • “它的行为就像 vidmem 甚至不存在” - 暗示你应该在 vidmem 是一个未定义的符号时得到一个编译错误。

标签: c gcc


【解决方案1】:

你可以声明全局变量,但你必须像这样在 main 内部初始化: char* 视频;

char* vidmem;

int main()
{
    vidmem = (char*)0xb8000;

    vidmem[0] = 'x';
    vidmem[1] = 0x0f;
}

【讨论】:

  • 这不是在解释什么是错的以及为什么,而是给出一个解决方法。
【解决方案2】:

我不明白为什么这个问题有这么多反对票。这是一个完全有效且有趣的问题,我在 1 小时前遇到了同样的问题。

问题在于,在正常情况下,例如,当链接器生成要在 Linux 上运行的可执行文件时,全局变量存储在 .data 部分中,它们的值是可执行文件的一部分。现在,在您的场景中,您正在生成原始二进制数据并直接启动它。在这种情况下,您需要向链接器指定全局变量应存储在映像中的位置。例如,您可以通过-Tdata 0x6000 将它们从地址 0x6000 开始存储。然后,在加载您的操作系统时,请务必在访问全局变量之前将这部分图像加载到内存中。

【讨论】:

    猜你喜欢
    • 2017-09-20
    • 2014-11-17
    • 1970-01-01
    • 1970-01-01
    • 2020-03-05
    • 2015-02-06
    • 1970-01-01
    • 2019-07-29
    • 1970-01-01
    相关资源
    最近更新 更多