繁体   English   中英

为什么此汇编代码无法打印到 VGA 文本模式视频 memory?

[英]Why does this assembly code not working to print to VGA text mode video memory?

我有以下汇编代码。 我正在尝试为 go 创建一个小型引导加载程序,使其进入 32 位保护模式。 进入保护模式后,我需要打印到 VGA 文本模式视频 memory (0xb8000) 以进行测试。 我的代码不起作用。 我从 web 周围的各种资源中找到了代码,并了解到大多数都有类似的代码可以正常工作,例如:Print characters to screen ASM in protected mode 我的代码不起作用:

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

它输出以下结果:

在此处输入图像描述

为什么附加零之前的指令

mov dword [di], 0xb8000

虽然它应该是

mov word [0xb8000], 0x0769

当您拥有此数据块时:

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 位模式下执行该部分的 far 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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM