Why is my char * passed correctly?

Problem statement (using a far-fetched example):

Works as expected ('b' prints to the screen):

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]; } 

Doesn't work as expected ( \0 is printed on the screen):

 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]; } 

In other words, if I pass const char* directly, it will not pass correctly. const char* I get into Foo , one way or another indicating a memory reset. What am I doing wrong?

Background information (on request):

I am developing an operating system for pleasure using the manual I found here . The manual usually assumes that you are running on a unix based computer, but I am developing on a PC, so I use MinGW so that I have access to gcc, ld, etc. In the manual, I am now on page 54, where you just downloaded your own kernel. Instead of just showing "X" as the manual teaches, I decided to use my existing C / C ++ knowledge to try and write my own rudimentary print line function. It is assumed that the function takes const char* and writes it, char to char, in video memory. There are currently three files involved in the project:

  • Boot sector - compiled via NASM to .bin file
  • Kernel input procedure - compiled without binding via NASM to .o associated with the kernel
  • Kernel - compiled through gcc, associated with the kernel input procedure using the ld command, which creates a .bin that is added to the .bin file created by the boot sector

After creating the combined .bin file, I convert it to .VDI (VirtualBox disk image) and run it in the virtual machine I installed.

Additional information :

I just noticed that when VirtualBox converts a .bin file to .vdi, it reports different sizes for two examples. I had a hunch that perhaps the string is completely excluded from the compiled product. Of course, when I look at .bin for the first example in the hex editor, I can find the text "bar", but I can not, when I look at the hexadecimal dump for .bin of the second example.

This makes me think that the compilation process that I use has a flaw somewhere. Here are the commands I use:

 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 is what gets converted to the .vdi file that is used in vm.

+7
c
source share
1 answer

In the first example, the compiler (or at least can) puts the data to initialize the automatic array directly in the code (the .text section - movements with immediate values ​​are used when I try to do this).

In the second example, the string literal is placed in the .rodata section, and the code will contain a link to this section.

Your objcopy command objcopy copies the .text section, so the line will not be in the final binary. You must add a .rodata section or completely remove -j .text .

+6
source share

All Articles