虽然循环没有写入视频内存

时间:2016-11-21 18:22:27

标签: c x86 operating-system osdev

我正在编写自己的操作系统作为家庭作业,我的C代码遇到了一些麻烦。我已经设置了我的引导头和链接器文件以及一个打印' H'的简单汇编脚本。然后调用我的C代码。汇编代码打印到视频内存很好(我打印到0xb8000)但我的C代码中的while循环不是。

const char *str = "My first kernel";
char *vidptr = (char*)0xb8002; //My ASM code writes to 0xb8000 for testing purposes
while(*str){
    *vidptr++ = 0x07;
    *vidptr++ = *str++;
}
vidptr[0] = 0x07;
vidptr[1] = 'f';

' H'和' f'字符打印得很好,但我的循环不打印任何东西到屏幕上。我尝试了多种编写循环的方法,例如

unsigned int j = 0;
char c;
while(c = *(str++)){
    vidptr[j] = 0x07;
    vidptr[j+1] = c;
    j+=2;
}

当然我已经尝试了

int i, j;
while(str[i] != '\0'){
    vidptr[j] = 0x07;
    vidptr[j+1] = str[i];
    i++;
    j+=2;
}

但似乎没有任何效果。我很困惑。

编辑:

我做了一些小改动,导致str中的字符被打印到屏幕上。我只是将vidptr更改为指向整数的指针。

int *vidptr = (int*)0xb8000;

这似乎有效。但是,当vidptr被声明为char指针时,我仍然感到困惑的原因是它为什么不起作用。即使我宣布它不稳定,我仍然没有输出到屏幕。

编辑2:

根据要求,这是有效的ASM代码。

global start
extern main

section .text

bits 32

start:
    mov word [0xb8000], 0x0748
    mov esp, stack_space
    call main
    hlt

section .bss
resb 8192
stack_space: 

main是我上面提供的C代码中的函数。

我的Github Repository可以找到我的源代码的完整副本。我的Makefile是:

default: build

.PHONY: clean

build/boot_header.o: multiboot_header.asm
    mkdir -p build
    nasm -f elf64 multiboot_header.asm -o build/boot_header.o

build/asmk.o: kernel.asm
    mkdir -p build
    nasm -f elf64 kernel.asm -o build/asmk.o

build/ckern.o: kernel.c
    gcc -m64 -c kernel.c -o build/ckern.o

build/kernel.bin: build/boot_header.o build/asmk.o build/ckern.o link.ld
    ld -n -o build/kernel.bin -T link.ld build/boot_header.o build/ckern.o build/asmk.o

build/os.iso: build/kernel.bin grub.cfg
        mkdir -p build/isofiles/boot/grub
        cp grub.cfg build/isofiles/boot/grub
        cp build/kernel.bin build/isofiles/boot/
        grub-mkrescue -o build/os.iso build/isofiles

run: build/os.iso
    qemu-system-x86_64 -curses -cdrom build/os.iso

build: build/os.iso

clean:
    rm -rf build

1 个答案:

答案 0 :(得分:1)

来自上述评论:

  

在您的更新中,您执行了mov word [0xb8000], 0x0748。这将16位字0x0748移动到0xb8000。因为x86是小端,所以当放入存储器时,一个字被存储到最高有效字节的最低有效字节。因此0xb8000将在其中具有0x48并且在0b8001处具有0x07。请参阅上面的评论,关于您将字节颠倒过来。 - Michael Petch 2016年11月21日19:33