2014-10-12 2 views
7

Постановка задачи (используя надуманный пример):Почему мой char * не проходит правильно?

Работа, как и ожидалось ('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* напрямую, это происходит неправильно. const char* Я получаю в Foo указывает на обнуление памяти как-то. Что я делаю не так?

информация Справочная (по запросу):

Я занимаюсь разработкой операционной системы для удовольствия, используя руководство, я нашел here. Руководство обычно предполагает, что вы работаете на компьютере на основе unix, но я развиваюсь на ПК, поэтому я использую MinGW, чтобы у меня был доступ к gcc, ld и т. Д. В руководстве я сейчас на странице 54, где вы только что загрузили свое собственное ядро. Вместо того, чтобы просто показывать «Х», как учит руководство, я решил использовать мои существующие знания C/C++, чтобы попытаться написать собственную рудиментарную функцию строки печати. Предполагается, что функция принимает const char* и записывает ее char char, в видеопамять. Три файлы в настоящее время участвует в проекте:

  • Загрузочный сектор - скомпилирован через NASM в .bin файл
  • Запись обычного ядра - скомпилированный без привязки через NASM к .о, связанный с ядром
  • ядро ​​- скомпилирован через GCC, связанные вместе с рутиной ввода ядра с помощью команды LD, которая производит .bin, который добавляется в файл .bin создаваемого загрузочного сектора

После того, вместе взятых. файл bin создается, я конвертируя его в .VDI (VirtualBox Disk Image) и запуская его в виртуальной машине, которую я настроил.

Дополнительная информация:

Я просто заметил, что когда 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 файл, который используется в виртуальной машине.

+0

Что такое str внутри foo? –

+2

Что такое str и где вы печатаете? – sas

+0

Запуск в окнах. Скомпилирован с использованием gcc и ld через MinGW. Есть вероятность, что некоторые из параметров моей командной строки для ld неверны, но большая часть кода работает нормально ... –

ответ

6

В вашем первом примере компилятор (или, по крайней мере, может) помещает данные для инициализации автоматического массива прямо в коде (раздел .text - перемещение с немедленными значениями используется, когда я пытаюсь это сделать).

С вашим вторым примером строковый литерал помещается в раздел .rodata, и код будет содержать ссылку на этот раздел.

Ваша команда objcopy копирует только раздел .text, поэтому строка будет отсутствовать в окончательном двоичном формате. Вы должны добавить раздел .rodata или полностью удалить -j .text.

Смежные вопросы