2014-10-12 26 views
7

Sorun bildirimi (zoraki bir örneğini kullanarak):Neden char * doğru bir şekilde geçmiyor?

beklendiği gibi çalışma ('b' ekrana yazdırılır):

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 ekrana yazdırılır) beklendiği gibi Çalışmıyor:

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

Başka bir deyişle, const char* doğrudan doğruya iletirse, doğru şekilde geçmez. const char*Foo numaralı bağlantıda bir şekilde bellek sıfırlandı. Neyi yanlış yapıyorum? (Istendiği gibi)

Arkaplan bilgisi:

ben here bulduğu kılavuzunu kullanarak, eğlence için bir işletim sistemi geliştiriyorum. Kılavuz genellikle unix tabanlı bir makinede olduğunuzu varsayar, ancak bir PC üzerinde geliştiriyorum, bu yüzden MinGW kullanıyorum, böylece gcc, ld, vb. Erişimim var. Rehberde şu anda sayfadayım 54, özel çekirdeğinizi önyüklemişsiniz. Kılavuz olarak sadece bir 'X' göstermekten ziyade, kendi yazımsal dize işlevimi yazmayı denemek için mevcut C/C++ bilgimi kullanmaya karar verdim. Fonksiyonun bir const char* alması ve onu char olarak char'in video belleğe yazması gerekiyor. Üç dosyaları şu anda projeye dahil olan:

  • önyükleme kesimi - Bir .bin dosyası
  • çekirdek giriş rutin için NASM'ın aracılığıyla derlenmiş - Bir .o kadar NASM'ın aracılığıyla bağlamadan derlenmiş çekirdek karşı bağlanmış
  • çekirdek - gcc yoluyla derlenmiş, ld komutu ile çekirdek giriş rutin ile birlikte bağlantılı, önyükleme kesimi bir araya kez

üretilen bin dosyasına ekli olan bir .bin'i üretir. bin dosyası üretildi, ben .VDI (VirtualBox Disk Image) 'a çeviriyor ve bunu bir VM'de çalıştırıyorum.

Ek bilgiler:

Sadece VirtualBox VDI için .bin dosya dönüştürme durumunda, bu iki örnek için farklı boyutlar bildiriyor fark ettim. Bir ipucunun, belki de dizinin tamamen derlenmiş üründen çıkarıldığını anladım. Tabii ki, bir hex editöründe ilk örnek için .bin'e baktığımda, "bar" metnini bulabilirim, ancak ikinci örnekteki .bin için bir hex dökümüne baktığımda bunu yapamam.

Bu, kullanıyorum derleme işleminin bir yerde bir hata olduğuna inanmamı sağlıyor.

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 vm kullanılan VDI dosyasına dönüştürülür budur: İşte kullanıyorum komutlardır.

+0

İçinde str nedir? –

+2

str nedir ve nereye yazdırıyorsunuz? – sas

+0

Pencerelerde çalışıyor. MinGW ile gcc ve ld kullanılarak derlendi. Ld için komut satırımın bazı seçeneklerinin doğru olma ihtimali yoktur, ancak çoğu kod iyi çalışır ... –

cevap

6

İlk örneğinizde, derleyici, koddaki otomatik diziyi doğru olarak başlatmak için verileri (en azından, yapabilir) koyar (.text bölümü - bunu denediğimde anlık değerler içeren hamleler kullanılır).

İkinci örneğinizde dize değişmezi .rodata bölümüne eklenir ve kod bu bölüme bir başvuru içerir.

objcopy komutunuz yalnızca .text bölümünü kopyalar, böylece dize son ikilide eksik olur. .rodata bölümünü eklemelisiniz veya -j .text'u tamamen kaldırmalısınız.

İlgili konular