gpt4 book ai didi

c - 为什么我的 char* 没有正确传递?

转载 作者:太空狗 更新时间:2023-10-29 17:11:06 29 4
gpt4 key购买 nike

问题陈述(使用人为的示例):

按预期工作('b' 打印到屏幕上):

void Foo(const char* bar);

void main()
{
const char bar[4] = "bar";
Foo(bar);
}

void Foo(const char* bar)
{
// Pointer to first text cell of video memory
char* memory = (char*) 0xb8000;
*memory = bar[0];
}

未按预期工作(\0 打印到屏幕上):

void Foo(const char* bar);

void main()
{
Foo("bar");
}

void Foo(const char* bar)
{
// Pointer to first text cell of video memory
char* memory = (char*) 0xb8000;
*memory = bar[0];
}

换句话说,如果我直接传递 const char*,它不会正确传递。我在 Foo 中得到的 const char* 以某种方式将内存清零。我做错了什么?

背景信息(根据要求):

我正在开发一个有趣的操作系统,使用我找到的指南 here .该指南通常假设您使用的是基于 unix 的机器,但我是在 PC 上开发,所以我使用 MinGW 以便我可以访问 gcc、ld 等。在指南中,我当前位于第 54 页,您刚刚在此处引导了自定义内核。我决定使用现有的 C/C++ 知识来尝试编写自己的基本打印字符串函数,而不是像指南所教的那样简单地显示“X”。该函数应该采用 const char* 并将其一个字符一个字符地写入视频内存。项目目前涉及三个文件:

  • 引导扇区 - 通过 NASM 编译为 .bin 文件
  • 内核入口例程——在没有通过 NASM 链接到 .o 的情况下编译,链接到内核
  • 内核 - 通过 gcc 编译,通过 ld 命令与内核入口例程链接,产生一个 .bin 附加到引导扇区产生的 .bin 文件

生成组合的 .bin 文件后,我将其转换为 .VDI(VirtualBox 磁盘镜像)并在我设置的 VM 中运行它。

附加信息:

我刚刚注意到,当 VirtualBox 将 .bin 文件转换为 .vdi 时,它报告两个示例的大小不同。我有一种预感,也许该字符串已从编译后的产品中完全省略。果然,当我在十六进制编辑器中查看第一个示例的 .bin 时,我可以找到文本“bar”,但是当我查看第二个示例的 .bin 的十六进制转储时,我找不到。

这让我相信我正在使用的编译过程在某处存在缺陷。以下是我正在使用的命令:

nasm boot_sector.asm -f bin -o boot_sector.bin
nasm kernel_entry.asm -f elf -o kernel_entry.o
gcc -ffreestanding -c kernel.c -o kernel.o
ld -T NUL -o kernel.tmp -Ttext 0x1000 kernel_entry.o kernel.o
objcopy -O binary -j .text kernel.tmp kernel.bin
copy /b boot_sector.bin+kernel.bin os_image.bin

os_image.bin 是转换为 .vdi 文件的文件,在 vm 中使用。

最佳答案

对于您的第一个示例,编译器将(或至少可以)将数据放入代码中以初始化自动数组(.text 部分 - 当我使用立即值移动时试试这个)。

对于第二个示例,字符串文字放在 .rodata 部分,代码将包含对该部分的引用。

您的 objcopy 命令仅复制 .text 部分,因此最终二进制文件中的字符串将丢失。您应该添加 .rodata 部分,或完全删除 -j .text

关于c - 为什么我的 char* 没有正确传递?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26322890/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com