assembly 为什么这个简单的Forth不写入VGA文本缓冲区?

mw3dktmi  于 2023-06-23  发布在  其他
关注(0)|答案(1)|浏览(84)

我正在尝试为x86-64编写一个裸机Forth,使用Multiboot启动,但不使用ELF。为了检查我的进度,我试图让它写一个'A'字符的VGA文本输出,使用的话,我已经定义。下面是NASM大会:

[BITS 64]

LOADBASE equ 0x00100000
org LOADBASE
   
MULTIBOOT_HEADER_MAGIC equ 0x1BADB002
MULTIBOOT_HEADER_FLAGS equ 0x00010000        
CHECKSUM equ -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)

PS_SIZE equ 0x4000
CS_SIZE equ 0x4000

_start: ; in case we're using a custom bootloader
    jmp boot_entry    
    align 4

multiboot_header:
    dd MULTIBOOT_HEADER_MAGIC
    dd MULTIBOOT_HEADER_FLAGS
    dd CHECKSUM
    dd multiboot_header ; location of this header
    dd LOADBASE ; where to load the kernel
    dd end ; where to finish loading
    dd 00 ; bss end adress : not necessary
    dd boot_entry ; entry point

%macro next 0
mov rax, qword[rsi]
add rsi, 8
jmp [rax]
%endmacro
     
boot_entry:
    mov rsp, end + PS_SIZE
    mov rbp, end + PS_SIZE + CS_SIZE

    push rbx ; multiboot info
    push rax

    mov rsi, cold_start
    next

%macro pushc 1
    sub rbp, 8
    mov qword[rbp], %1
%endmacro

%macro popc 1
    mov %1, qword[rbp]
    add rbp, 8
%endmacro

%define link 0

%macro DP 2 ; define a primitive (name, label)
    %strlen namelen %1
    align 4

    global name_%2
    name_%2:
        dd link
        %define link name_%2
        db %1
        align 4
    
    global %2
    %2:
        dq code_%2
        align 4
    
    global code_%2
    code_%2:
%endmacro

%macro DC 2 ; define a colon word (name, label)
    %strlen namelen %1
    align 4

    global name_%2
    name_%2:
        dd link
        %define link name_%2
        db %1
        align 4
    
    global %2
    %2:
        dq docol
%endmacro

docol:
    pushc rsi
    add rax, 8
    mov rsi, rax
    next

cold_start:
    dq QUIT

DC "QUIT", QUIT
    dq LIT, 0x41, SHOW, QUIT

DC "SHOW", SHOW
    dq LIT, 0xB8000, BWRITE, LIT, 0x07, LIT, 0xB8001, BWRITE, EXIT

DP "EXIT", EXIT
    popc rsi
    next

DP "B@", BREAD
    pop rax
    mov bl, byte[rax]
    push rbx
    next

DP "B!", BWRITE
    pop rax
    pop rbx
    mov byte[rax], bl
    next

DP "LIT", LIT
    push qword[rsi]
    add rsi, 8
    next

end:

当然,此时宏的链表部分是不必要的,可以忽略。
我的问题是,这并没有写任何东西的VGA文本输出。到目前为止,我已经排除了 Boot 问题,因为在boot_entry部分中放置写入'A'的指令可以正常工作。

czfnxgou

czfnxgou1#

正如Jester所指出的,我正在编写64位汇编,但引导加载程序只提供32位保护模式。

相关问题