2016-11-02 32 views
3

私は、保護モードを入力して「こんにちは」印刷文字

をプリントアウトしようとしているしかし、その代わりに、それはちょうど私の経歴から「ロードOS」を出力するには、入る前に起こったコールを(中断しますpmode)そして他には何もありません。

マイBootloader.asm

%DEFINE KERNEL_LOAD_OFFSET 0x1000 

org 0x7c00 

bits 16 

xor ax, ax 
mov ds, ax 

start: jmp main 

Print: 
.print: 
    lodsb 
    or al, al 
    je .done 

    mov ah, 0x0E 
    int 0x10 

    .repeat: 
    jmp .print 

.done: 
    ret 

ResetFloppy: 
mov ah, 0x0 

int 0x13 
jc ErrorFloppy 
.done: 
    ret 

ReadFloppy: 

mov ah, 0x02 
int 0x13 

jc ErrorFloppy 

.done: 
    ret 

ErrorFloppy: 

mov si, msgErrorFloppy 
call Print 

jmp hang 


main: 
.print: 

    mov si, msg 
    call Print 

.loadFile: 
    mov al, 0xF 
    mov ch, 0x0 
    mov cl, 0x02 
    mov dh, 0x0 
    mov dl, 0x0 
    mov bx, KERNEL_LOAD_OFFSET 

    call ResetFloppy 
    call ReadFloppy 


.loadGDT: 
    lgdt [gdtr] 
.pM_start: 
    cli 
    pusha 

    mov eax, cr0 
    or al, 1 
    mov cr0, eax 

    popa 

    jmp 0x08:ljmp_pM 


bits 32 
ljmp_pM: 
    mov ax, 0x10 
    mov ds, ax 
    mov ss, ax 
    mov fs, ax 
    mov es, ax 
    mov gs, ax 

    jmp KERNEL_LOAD_OFFSET 

hang: 
jmp $ 

gdt: 
NULL_DESC: 
    dd 0   ; null descriptor 
    dd 0 

CODE_DESC: 
    dw 0xFFFF  ; limit low 
    dw 0   ; base low 
    db 0   ; base middle 
    db 10011010b ; access 
    db 11001111b ; granularity 
    db 0   ; base high 

DATA_DESC: 
    dw 0xFFFF  ; data descriptor 
    dw 0   ; limit low 
    db 0   ; base low 
    db 10010010b ; access 
    db 11001111b ; granularity 
    db 0   ; base high 

gdtr: 
    Limit dw 24   ; length of GDT 
    Base dd NULL_DESC ; base of GDT 

msg db "Loading OS", 13, 10, 0 
msgErrorFloppy db "There was an error with the floppy", 13, 10, 0 

FILL: 
times 510-($-$$) db 0 

BOOTSECTOR: 
dw 0xAA55 

Kernel.asm

bits 32 

mov dword [0xB8000], 0x07690748 

jmp $ 

そしてCompile.bat私が使用

nasm -f bin Dev/BootLoader.asm -o Bin/BootLoader.bin 
nasm -f bin Dev/Kernel.asm -o Bin/Kernel.bin 

dd if=Bin/BootLoader.bin of=Image/Image.img seek=0 
dd if=Bin/Kernel.bin of=Image/Image.img seek=1 conv=notrunc 

pause 

ボッシュhttp://prntscr.com/d24wmm

+8

「Hi」は左上隅にありますか? – Jester

+0

オハイオ州私の神私は実際にはとても愚かです:Dありがとう:Dこれは答えとして投稿 –

答えて

0

32ビット保護モードでは、BIOSが16ビットリアルモードのコードで書かれているため、BIOSを使用できません。だから、あなたはこのように、ビデオメモリにアクセスする必要があります。

mov ebx,0xb8000 ; The video address 
    mov al,'!'   ; The character to be print 
    mov ah,0x0F  ; The color: white(F) on black(0) 
    mov [ebx],ax  ; Put the character into the video memory 

次にあなたが画面の先頭に!を見ることができます。あなただけのカーソル位置に印刷したい場合は、カーソルは次のようにオフセットを得ることができます:あなたのコードの効率性を高めるために、32ビットプロテクトモードで

mov dx,0x3D4  ; Tell the control I/O port to get the lower byte of 
    mov al,0x0F  ; the cursor offset 
    out dx,al 
    mov dx,0x3D5  ; Switch to data I/O port 
    in al,dx   ; Get the cursor offset's lower byte 

    mov dx,0x3D5  ; Tell the control I/O port to get the higher byte of 
    mov al,0x0E  ; the cursor offset 
    out dx,al 
    mov dx,0x3D5  ; Switch to data I/O port 
    in al,dx   ; Get the higher byte 

    imul ax,2   ; Because a character in video memory costs 2 bytes 
         ; (i.e character and attribute), we need to twice the cursor offset 

、あなたはいくつかの高レベルの言語を使用することができます機能を作成するにはCのようにします。これは実際にコードの可読性を高めました。

+0

最初のコードブロックはメモリに格納されません。私はあなたがページングが無効であるか、または直接マップされていると仮定しているので、あなたは 'mov [ebx]、ax'を省略したと思います。ところで、あなたは 'mov word [0xb8000]、(0x0F << 8)と書くことができました。 '!' '。 –

+0

また、 'mul ax、2 'はx86命令ではありません。 'imul ax、2'は有効ですが、それを使って愚かな力で乗算します。 'shl ax、1'を使います。そして 'al'とshiftを書く前に' eax'をゼロにすることを忘れないでください。 –

+0

@PeterCordesありがとう、私は答えを編集します –