2014-10-12 20 views
7

Vấn đề tuyên bố (sử dụng một ví dụ contrived):Tại sao char * của tôi không chính xác?

làm việc như mong đợi ('b' được in vào màn hình):

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

Không làm việc như mong đợi (\0 được in vào màn hình):

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

Nói cách khác, nếu tôi chuyển trực tiếp const char*, nó không chuyển đúng. const char* Tôi nhận được trong Foo điểm để zeroed ra bộ nhớ bằng cách nào đó. Tôi đang làm gì sai?

thông tin nền (theo yêu cầu):

Tôi đang phát triển một hệ điều hành cho vui, sử dụng một hướng dẫn tôi tìm thấy here. Hướng dẫn này giả định bạn đang sử dụng máy tính dựa trên Unix, nhưng tôi đang phát triển trên PC, vì vậy tôi đang sử dụng MinGW để tôi có quyền truy cập vào gcc, ld, v.v. Trong hướng dẫn, tôi hiện đang ở trên trang 54, nơi bạn vừa khởi động hạt nhân tùy chỉnh của mình. Thay vì chỉ hiển thị chữ 'X' làm hướng dẫn, tôi quyết định sử dụng kiến ​​thức C/C++ hiện có của mình để cố gắng viết hàm chuỗi in thô sơ của riêng mình. Chức năng này được yêu cầu lấy const char* và ghi nó, char bằng char, vào bộ nhớ video. Ba file hiện đang tham gia dự án:

  • Boot sector - biên soạn qua NASM vào một tập tin .bin
  • Mục thói quen kernel - biên soạn mà không cần kết nối qua NASM đến một .o, liên kết chống lại hạt nhân
  • kernel - biên soạn qua gcc, liên kết cùng với thói quen nhập hạt nhân thông qua các lệnh ld, trong đó sản xuất một .bin được gắn vào file .bin được sản xuất bởi các boot sector

Khi gộp lại. tệp bin được tạo, tôi chuyển đổi nó sang .VDI (VirtualBox Disk Image) và chạy nó trong một máy ảo mà tôi đã thiết lập.

thông tin bổ sung:

Tôi chỉ nhận thấy rằng khi VirtualBox là chuyển đổi các tập tin .bin để .vdi, nó được báo cáo kích cỡ khác nhau cho hai ví dụ. Tôi đã có một linh cảm mà có thể chuỗi đã được bỏ qua hoàn toàn từ các sản phẩm biên dịch. Chắc chắn, khi tôi nhìn vào .bin cho ví dụ đầu tiên trong một trình soạn thảo hex, tôi có thể tìm thấy văn bản "bar", nhưng tôi không thể khi tôi nhìn vào một dump hex cho .bin của ví dụ thứ hai.

Điều này khiến tôi tin rằng quá trình biên dịch tôi đang sử dụng có một lỗ hổng trong đó ở đâu đó. Dưới đây là các lệnh tôi đang sử dụng:

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 là những gì được chuyển đổi thành tệp .vdi được sử dụng trong vm.

+0

Đường nối trong foo là gì? –

+2

str là gì và bạn đang in ở đâu? – sas

+0

Chạy trong cửa sổ. Biên dịch bằng gcc và ld thông qua MinGW. Có khả năng một số tùy chọn dòng lệnh của tôi cho ld không đúng, nhưng hầu hết mã đều chạy tốt ... –

Trả lời

6

Với ví dụ đầu tiên của bạn, trình biên dịch sẽ (hoặc ít nhất, có thể) đưa các dữ liệu để khởi tạo mảng tự động ngay trong mã (.text phần - di chuyển với các giá trị tức thời được sử dụng khi tôi cố gắng này ra).

Với ví dụ thứ hai của bạn, chuỗi ký tự được đặt trong phần .rodata và mã sẽ chứa tham chiếu đến phần đó.

Lệnh objcopy của bạn chỉ sao chép phần .text, do đó chuỗi sẽ bị thiếu trong tệp nhị phân cuối cùng. Bạn nên thêm phần .rodata hoặc xóa hoàn toàn -j .text.

Các vấn đề liên quan