【问题标题】:C char array always empty. Kernel developmentC char 数组始终为空。内核开发
【发布时间】:2015-07-01 03:11:18
【问题描述】:

我正在编写一个 32/64 位内核。我有一个奇怪的问题,当我尝试将 const char*char *char [] 传递给函数时,数组总是空的。

例如,

我有一个kmain,它会在我写的时候进行 gdt、idt、isrs、irq、视频和定时器初始化:

 test_func("test");

test_func(char * string) 调试代码:

void test_func(char * string)
{
    if(string[0] == '\0'){
        putch('n');
    }else{
        putch('o');
    }
}

我总是在屏幕上显示“n”。

如果我测试:

 if (string == NULL){
       putch('n');
 }else{
       putch('o');
       putch(string[0]);
 }

我得到o 没有字符串的第一个字符

对于链接和编译,我正在使用

ld -m i386linux -T linker/link.ld  -nostdlib  -o kern.my ../obj/start.o \
                      ../obj/main.o \
                      ../obj/scrn.o \
                       ../obj/gdt.o \
                       ../obj/idt.o \
                      ../obj/isrs.o \
                       ../obj/irq.o \
                     ../obj/timer.o \
                        ../obj/io.o \
                     ../obj/yshell.o \
                        ../obj/kb.o

我正在使用 Qemu i386 测试 kern.my

[链接器脚本]

OUTPUT_FORMAT("binary")
ENTRY(start)
phys = 0x100000;
SECTIONS
{
  .text phys : AT(phys) {
    code = .;
    *(.text)
    *(.rodata)
    . = ALIGN(4096);
  }
  .data : AT(phys + (data - code))
  {
    data = .;
    *(.data)
    . = ALIGN(4096);
  }
  .bss : AT(phys + (bss - code))
  {
    bss = .;
    *(.bss)
    . = ALIGN(4096);
  }
  end = .;
}

我使用 Qemu 和 GDB,我的信息寄存器:

eax            0x1  1
ecx            0x0  0
edx            0x3d5    981
ebx            0x9500   38144
esp            0x104fe0 0x104fe0
ebp            0x0  0x0
esi            0x0  0
edi            0x108000 1081344
eip            0x100356 0x100356
eflags         0x6  [ PF ]
cs             0x8  8
ss             0x10 16
ds             0x10 16
es             0x10 16
fs             0x10 16
gs             0x10 16

【问题讨论】:

  • 请发布您正在使用的实际代码,并将其简化为您遇到的问题。
  • 发布您的链接器脚本。
  • 我发布了链接描述文件

标签: c gcc kernel ld


【解决方案1】:

问题出在我的链接器脚本上。

我正在使用 (.rodata) ,将其更改为 (.rodata*) 解决问题

rodata 是可显示字符串存储在 ELF 文件中的部分,链接器假定它应该转到偏移量 0,而整个内核链接到 0x100000

GCC 将标记为 const 的全局变量放在名为 .rodata 的单独部分中。 .rodata 也用于存储字符串常量。

由于 .rodata 部分的内容不会被修改,它们可以 放在 Flash 中。必须修改链接描述文件以适应这种情况。

【讨论】:

    【解决方案2】:

    它是 != NULL 的事实让我觉得你在某处糟糕地访问了内存 - 可能是一个接近正在传递的字符串的 mallocing 的变量。

    我不记得常量字符串是如何存储在机器代码中的 - 但我认为它是类似的,只是使用动态的、C 管理的内存管理。

    因此请检查以确保您的数组永远不会超出其范围等。 当您在单独的文件中运行代码时,还要验证您是否获得了 -expected- 输出?

    您还可以发布 test[-1] 和 test[1] 是/评估什么,以及每次运行是否一致?

    【讨论】:

      猜你喜欢
      • 2017-04-20
      • 2012-04-20
      • 2017-01-07
      • 1970-01-01
      • 2017-06-26
      • 2018-12-26
      • 2012-03-06
      • 2012-10-09
      • 1970-01-01
      相关资源
      最近更新 更多