Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 32位保护模式引导加载程序光标在屏幕上快速移动,没有显示代码?_Assembly_X86_Nasm_Bootloader_Osdev - Fatal编程技术网

Assembly 32位保护模式引导加载程序光标在屏幕上快速移动,没有显示代码?

Assembly 32位保护模式引导加载程序光标在屏幕上快速移动,没有显示代码?,assembly,x86,nasm,bootloader,osdev,Assembly,X86,Nasm,Bootloader,Osdev,我正在从头开始编写一个基本内核,并将其用作我的教科书。我已经编写了基本的16位引导加载程序,并且根据本文编写了切换到保护模式的代码。它定义一个基本的通用描述符表,加载它,并在cr0特殊寄存器中翻转一位。然而,当我尝试引导代码时,我会看到一个光标反复地在屏幕底部移动。这我不明白,因为我还没有展示任何东西。当我试图显示一个字符串时,我只得到了屏幕底部的光标。这是我的一些代码 BITS 16 ; switch to 32 bit protected mode switch_to_pm: cl

我正在从头开始编写一个基本内核,并将其用作我的教科书。我已经编写了基本的16位引导加载程序,并且根据本文编写了切换到保护模式的代码。它定义一个基本的通用描述符表,加载它,并在cr0特殊寄存器中翻转一位。然而,当我尝试引导代码时,我会看到一个光标反复地在屏幕底部移动。这我不明白,因为我还没有展示任何东西。当我试图显示一个字符串时,我只得到了屏幕底部的光标。这是我的一些代码

BITS 16
; switch to 32 bit protected mode
switch_to_pm:

    cli
    lgdt [gdt_descriptor]

    mov eax, cr0
    or eax, 0x1
    mov cr0, eax

    jmp CODE_SEG:init_pm

BITS 32

init_pm:

    mov ax, DATA_SEG
    mov ds, ax
    mov ss, ax
    mov es, ax
    mov fs, ax
    mov gs, ax

    ;mov ebp, 0x90000
    ;mov esp, ebp

BEGIN_PM:
    ;mov ebx, 0xb8000
    ;mov ah, 0x0f
    ;mov al, '3'
    ;mov [ebx], ax
    ;add ebx, 2
    ;mov al, '2'
    ;mov [ebx], ax
    jmp $
这是做开关的部分。它是从主引导加载程序文件调用的。如果需要该代码,我可以编辑我的问题以包含它。谢谢你们。我真的搞不懂这个问题,但这是我第一次编写32位引导加载程序

boot_loader.asm:

BITS 16
[org 0x7c00]

start:
    mov [BOOT_DRIVE], dl

    mov bp, 0x9000 ; setup our stack
    mov sp, bp

    mov dl, [BOOT_DRIVE]
    call disk_load
    call switch_to_pm

    jmp $


disk_load:
    push dx
    mov bx, 0x1000 ; adress to write to
    mov dh, 15     ; # sectors to read
    mov ah, 0x02   ; sector to start at ??
    mov al, dh     ; same # sectors
    mov ch, 0x00   ; cylinder to read ?
    mov dh, 0x00   ; head to read (switch?)
    mov cl, 0x02   ; sector to start at ??

    int 0x13

    jc disk_error

    pop dx
    cmp dh, al
    jne disk_error
    ret

disk_error:
    mov ah, 0x0e
    mov bx, DISKERR
    sub bx, 1
disk_error_print:
    add bx, 1
    cmp byte [bx], 0x0
    je disk_error_done
    mov al, [bx]
    int 0x10
    jmp disk_error_print
disk_error_done:
    jmp $


%include "boot/gdt.asm"
%include "boot/switch_to_pm.asm"


; Global vars
BOOT_DRIVE: db 0
DISKERR:
    db "error reading disk" , 0
; Bootsector padding
times 510-($-$$) db 0
dw 0xaa55
db "hello"
gdt.asm:

gdt_start:

gdt_null:
    dd 0x0
    dd 0x0
gdt_code: ; the code segment descriptor
    dw 0xffff
    dw 0x0
    dw 0x0
    db 10011010b
    db 11001111b
    db 0x0
gdt_data: ; the data segment descriptor
    dw 0xffff
    dw 0x0
    dw 0x0
    db 10010010b
    db 11001111b
    db 0x0
gdt_end:

gdt_descriptor:
dw gdt_end - gdt_start - 1
dd gdt_start

CODE_SEG equ gdt_code - gdt_start
DATA_SEG equ gdt_data - gdt_start

你能给我们看看你所有的代码吗?一个最小的可验证的完整示例是获得答案的最佳选择。我列出了完整的代码@MichaelPetch谢谢。另外,如果投票结束我的问题的人能帮助我理解我的问题是什么,以及我如何才能把它做得更好,我会非常感激。谢谢。好的,我可以构建你的引导加载程序并在QEMU和BOCHS中运行,你的引导加载程序运行并打印
错误读取磁盘
。磁盘读取的参数看起来有误。你建议光标在屏幕上移动?我看不出来。您使用什么命令来构建引导加载程序,然后使用什么命令来运行它?你使用哪种模拟器?您发布的代码是您实际使用的代码吗?如果您因为错误而注释掉对
disk\u load
的调用,并且只处理GDT的问题,那么您应该能够有所作为。首先,在引导加载程序开始时,您应该显式地将DS设置为零,因为您使用的组织是0x7c00。添加异或ax,ax
mov ds,ax
。主要问题是GDT
GDT\U代码
GDT\U数据
中存在bug。两者都以
dw 0xffff dw 0x0 dw 0x0开始
问题是最后一个0x00应该是一个字节而不是一个字。将两者都更改为
dw 0xffff dw 0x0 db 0x0
。这会导致格式不正确的GDT条目。一旦您确定您应该能够取消注释屏幕左上角打印32的代码,并且理论上它应该可以工作,您可以向我们显示您的所有代码吗?一个最小的可验证的完整示例是获得答案的最佳选择。我列出了完整的代码@MichaelPetch谢谢。另外,如果投票结束我的问题的人能帮助我理解我的问题是什么,以及我如何才能把它做得更好,我会非常感激。谢谢。好的,我可以构建你的引导加载程序并在QEMU和BOCHS中运行,你的引导加载程序运行并打印
错误读取磁盘
。磁盘读取的参数看起来有误。你建议光标在屏幕上移动?我看不出来。您使用什么命令来构建引导加载程序,然后使用什么命令来运行它?你使用哪种模拟器?您发布的代码是您实际使用的代码吗?如果您因为错误而注释掉对
disk\u load
的调用,并且只处理GDT的问题,那么您应该能够有所作为。首先,在引导加载程序开始时,您应该显式地将DS设置为零,因为您使用的组织是0x7c00。添加异或ax,ax
mov ds,ax
。主要问题是GDT
GDT\U代码
GDT\U数据
中存在bug。两者都以
dw 0xffff dw 0x0 dw 0x0开始
问题是最后一个0x00应该是一个字节而不是一个字。将两者都更改为
dw 0xffff dw 0x0 db 0x0
。这会导致格式不正确的GDT条目。一旦您解决了这个问题,您应该能够取消注释在屏幕左上角打印32的代码,理论上它应该可以工作