在实模式下gcc gnu汇编内核

时间:2016-12-20 04:00:15

标签: x86 stack kernel inline-assembly bootloader

我正在尝试在gcc gnu程序集中构建一个16位内核,而我的引导程序是用纯汇编编写的,但我在打印字符串时遇到问题,而单个字符是可以的:

这是我的bootloader.asm:

org 0x7c00
bits    16



    section .text
mov ax,0x1000
mov ss,ax
mov sp,0x000
mov esp,0xfffe



xor ax,ax
mov es,ax 
mov ds,ax


mov [bootdrive],dl


mov bh,0
mov bp,zeichen

mov ah,13h
mov bl,06h
mov al,1
mov cx,6
mov dh,010h
mov dl,01h

int 10h

load:
mov dl,[bootdrive]
xor ah,ah
int 13h
jc load

load2:
mov ax,0x1000
mov es,ax
xor bx,bx

mov ah,2
mov al,1
mov cx,2
xor dh,dh

mov dl,[bootdrive]
int 13h
jc load2


mov ax,0
mov es,ax

mov bh,0
mov bp,zeichen3

mov ah,13h
mov bl,06h
mov al,1
mov cx,13
mov dh,010h
mov dl,01h

int 10h

mov ax,0x1000
mov es,ax
mov ds,ax
jmp 0x1000:0x000

zeichen db  'hello2'
zeichen3 db 'soweit so gut'
bootdrive db 0
times   510 - ($-$$)    hlt
dw  0xaa55

这里是我的kernel.c:

asm("jmp main");


void  print()
{
    for(int i=0;i<5;i++)
    {
    asm("mov $0x0e,%ah");
    asm("mov $0x00,%bh");
    asm("mov %0,%%al":: "" ('g'));
    asm("int $0x10");
    }
}
void main()
{

    asm("mov    $0x1000,%eax;"
        "mov    %eax,%es;"
        "mov    %eax,%ds");
    const char string[]="hall0";
    print();
    for(int i=0;i<5;i++)
    {
        asm("mov $0x0e,%ah");
        asm("mov $0x00,%bh");
        asm("mov %0,%%al":: "" (string[i]));
        asm("int $0x10");
    }

    asm(".rept 512;"
        " hlt ;"
        ".endr");
}

我使用的命令是: nasm -f bin -o bootloader.bin bootloader.asmgcc kernel.c -c -o kernel.o -m16 -nostdlib -ffreestanding&&ld -melf_i386 kernel.o -o kernel.elf&&objcopy -O binary kernel.elf kernel.o&&cat bootloader.bin kernel.elf>myOS.bin&&qemu-system-i386 myOS.bin 在我的Linux Mint Cinnamon版本18上。 它打印出10克后“soweit so gut”这些是它应该打印的5克加上“hall0”的字符数,但我不打印“hall0”。 因此,我必须在bootloader.asm中使用gcc gnu汇编程序做错了,可能会设置堆栈错误或其他东西。 也许有人可以帮我做什么?

1 个答案:

答案 0 :(得分:-2)

您必须将'kernel.asm'编译为bin文件,然后执行cat命令