为什么这个汇编代码不能打印到VGA文本模式的视频存储器?

问题描述 投票:3回答:1

我有下面的汇编代码,我想创建一个小的bootloader来进入32位保护模式。我试图创建一个小的bootloader来进入32位保护模式,一旦进入保护模式,我需要打印到VGA文本模式的视频存储器(0xb8000)来进行测试。一旦进入保护模式,我需要打印到VGA文本模式的视频存储器(0xb8000)以进行测试。我的代码无法工作。我从网络上的各种资源中找到了代码,了解到大多数有类似的代码,可以正常工作,比如这个例子。在保护模式下将字符打印到屏幕ASM . 我的代码不能用。

bits 16

mov ah, 0x00  ;Set up video mode
mov al, 0x03
int 0x10

gdt_start:
        dq 0x0
gdt_code:
        dw 0xFFFF
        dw 0x0
        db 0x0
        db 10011010b
        db 11001111b
        db 0x0
gdt_data:
        dw 0xFFFF
        dw 0x0
        db 0x0
        db 10010010b
        db 11001111b
        db 0x0  

gdtr:
        dw 24
        dd gdt_start

lgdt [gdtr]

cli

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

jmp 0x08:protectedMode 

bits 32

protectedMode:
    mov ax, 0x10
    mov ds, ax
    mov es, ax 
    mov fs, ax
    mov gs, ax
    mov ss, ax

    mov word [0xb8000], 0x0769 

times 510 - ($-$$) db 0
dw 0xaa55

我用以下方法编译代码

nasm -fbin boot.asm -oboot.bin

然后用..:

qemu-system-x86_64 -fda boot.bin

它什么都不做。

当我用:

ndisasm boot.bin

它的输出结果如下。

enter image description here

为什么在加零之前的指令是:

mov dword [di], 0xb8000

当是

mov word [0xb8000], 0x0769
assembly x86 nasm disassembly bootloader
1个回答
4
投票

当你有这个数据块时。

gdt_start:
        dq 0x0
gdt_code:
        dw 0xFFFF
        dw 0x0
        db 0x0
        db 10011010b
        db 11001111b
        db 0x0
gdt_data:
        dw 0xFFFF
        dw 0x0
        db 0x0
        db 10010010b
        db 11001111b
        db 0x0  

gdtr:
        dw 24
        dd gdt_start

它位于执行路径中. 这个数据将作为代码被处理器执行,作为接下来的指令,在经过 int 0x10. 把这个移低一点,然后... mov word [0xb8000], 0x0769.

你还需要在执行该指令后添加一个无限循环,以防止执行过程中落到后面的任何垃圾中(如果你把它放在那里,那么GDT表)。

永远记住,汇编是非常低级的。无论你在代码中贴的是什么,无论是否有实际意义的指令,如果处理器有机会接触到它,都会被当作代码处理。它不会跳过数据,也不会在你写完最后一条指令后停止。


至于为什么指令反汇编是错误的,反汇编器不知道什么时候切换到32位模式。 它只是一个反汇编器,而不是模拟器,所以它看不到让CPU在32位模式下执行那部分指令的远期jmp的效果。

你可以在32位模式下拆解整个东西,然后(在拆解前发生一些乱七八糟的事情,让它与实际的指令边界恢复同步),它就会按照你的意图用这个来拆解。

ndisasm -b 32 boot.bin
...                 ;; some earlier mess of 16-bit code disassembled as 32
0000003B  8ED8              mov ds,eax
0000003D  8EC0              mov es,eax
0000003F  8EE0              mov fs,eax
00000041  8EE8              mov gs,eax
00000043  8ED0              mov ss,eax
00000045  66C70500800B0069  mov word [dword 0xb8000],0x769   ; correct disassembly
         -07
0000004E  0000              add [eax],al
00000050  0000              add [eax],al
© www.soinside.com 2019 - 2024. All rights reserved.