2014-10-12 54 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的計算機,但我正在使用PC進行開發,所以我使用MinGW以便可以訪問gcc,ld等。 在指南中,我目前處於頁面54,你剛剛引導你的定製內核。我不是簡單地按照指導教導顯示'X',而是決定使用我現有的C/C++知識來嘗試編寫我自己的基本打印字符串函數。該函數應該採取const char*並將它按char字符寫入視頻內存。 三個文件,目前參與該項目:

  • 引導扇區 - 通過NASM編譯成一個.bin文件
  • 內核輸入程序 - 無需通過NASM鏈接到的.o編譯,對內核鏈接
  • 內核 - 通過GCC編譯,通過ld命令與內核輸入程序沿着聯,其產生被附加到由引導扇區

一旦組合產生的bin文件一個的.bin。 bin文件生成,我是將其轉換爲.VDI(VirtualBox Disk Image)並在我設置的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文件。

+0

foo裏面的str是什麼? – 2014-10-12 07:34:39

+2

什麼是str和你在哪裏打印? – sas 2014-10-12 07:35:09

+0

在窗口中運行。通過MinGW使用gcc和ld進行編譯。有可能我的某些命令行選項不正確,但大多數代碼運行正常...... – 2014-10-12 07:41:35

回答

6

在你的第一個例子中,編譯器將(或者至少可以)將數據放在代碼中初始化自動數組右邊(.text部分 - 當我嘗試使用時立即使用移動值)。

在第二個示例中,字符串文字被放入.rodata部分,代碼將包含對該部分的引用。

您的objcopy命令僅複製.text部分,因此該字符串將在最終的二進制文件中丟失。您應該添加.rodata部分,或完全刪除-j .text

相關問題