C 字符数组始终为空。内核开发
C char array always empty. Kernel development
我正在编写 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] == '[=11=]'){
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
它是 != NULL 的事实让我觉得你在某处访问内存很糟糕 - 可能有一个变量接近正在传递的字符串的 mallocing。
我不记得常量字符串是如何存储在机器代码中的 - 但我认为它的完成方式类似,只是使用动态的 C 管理的内存管理。
因此请检查以确保您的数组永远不会写出它们的边界等。
当您 运行 单独文件中的代码时,还要验证您是否获得 -expected- 输出?
你还可以 post 测试[-1]和测试[1] is/evaluates,它们是否一致 运行?
问题出在我的链接描述文件上。
我正在使用 (.rodata) ,将其更改为 (.rodata*) 修复问题
rodata 是 ELF 文件中存储可显示字符串的部分,链接器假定它应该转到偏移量 0,而整个内核链接在 0x100000
GCC places global variables marked as const in a separate section, called .rodata. The .rodata is also used for storing string constants.
Since contents of .rodata section will not be modified, they can be
placed in Flash. The linker script has to modified to accomodate this.
我正在编写 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] == '[=11=]'){
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
它是 != NULL 的事实让我觉得你在某处访问内存很糟糕 - 可能有一个变量接近正在传递的字符串的 mallocing。
我不记得常量字符串是如何存储在机器代码中的 - 但我认为它的完成方式类似,只是使用动态的 C 管理的内存管理。
因此请检查以确保您的数组永远不会写出它们的边界等。 当您 运行 单独文件中的代码时,还要验证您是否获得 -expected- 输出?
你还可以 post 测试[-1]和测试[1] is/evaluates,它们是否一致 运行?
问题出在我的链接描述文件上。
我正在使用 (.rodata) ,将其更改为 (.rodata*) 修复问题
rodata 是 ELF 文件中存储可显示字符串的部分,链接器假定它应该转到偏移量 0,而整个内核链接在 0x100000
GCC places global variables marked as const in a separate section, called .rodata. The .rodata is also used for storing string constants.
Since contents of .rodata section will not be modified, they can be placed in Flash. The linker script has to modified to accomodate this.