【问题标题】:Why do I get the wrong address when referencing a global variable?为什么在引用全局变量时会得到错误的地址?
【发布时间】:2020-07-06 13:30:27
【问题描述】:

我正在尝试编写一个基本的操作系统来更好地理解操作系统的基础知识,但我遇到了一个奇怪的问题。切换到保护模式后,我跳入我的内核。在我的 kernel.cpp 文件中,我声明了以下全局变量(其中 IdtPointer_t 和 IdtEntry_t 都是结构。)

IdtPointer_t idtPtr;
IdtEntry_t idtEntries[256];

这会在 bss 部分创建 idtPtr 和 idtEntries 变量。 然后稍后在我的代码中执行以下操作时

IdtEntry_t* entry = &idtEntries[0];

&idtEntries[0] 返回的值不是正确的地址。使用 GDB 我已经完成了以下操作

p &idtEntries[0]
(IdtEntry_t *) 0x87a0 <idtEntries>
p entry
(IdtEntry_t *) 0x87e0 <idtEntries+64>

两个变量的位置之间有 64 字节的差异。为什么引用变量返回的地址与变量在内存中的存储位置不同?

另外,我正在使用 qemu i386 模拟器运行它。

【问题讨论】:

  • 如果更改idtPtridtEntries的声明顺序会发生什么?
  • 您是否在初始化 entry 和在 gdb 中查看它之间进行更改? minimal reproducible example 会有所帮助。
  • gdb 是否会错误地报告此问题 - 可能是因为您的编译已优化?
  • 这些行是否在同一个编译单元中?
  • 如果在代码中打印这些变量会得到什么?

标签: c++ memory operating-system


【解决方案1】:

为什么引用变量返回的地址与变量在内存中的存储位置不同?它不是。我强烈怀疑 GDB 显示的不是您认为的那样(尽管我不是 GDB 专家)。

假设您是在 linux 系统上开发此功能,我建议您使用 'nm' 的输出(或与交叉编译器相关)来补充您的观察结果。

nm -n <elf file>

这将可靠地为您提供内核/操作系统中所有符号及其地址的列表(按数字顺序排序)。然后将 'idtEntries' 和 'entry' 的地址与你在 GDB 中得到的地址进行比较。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-09-14
    • 2010-09-12
    • 1970-01-01
    • 2010-10-25
    • 2023-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多