Assembly 如何在32位NASM汇编中更改VGA

Assembly 如何在32位NASM汇编中更改VGA,assembly,nasm,32-bit,Assembly,Nasm,32 Bit,我正在尝试更改此代码中的VGA。人们说我可以使用int10h,但是,我在virtualbox中遇到了一个错误。我想在这一点上设置任何类型的vga屏幕。我设法设置了Globa描述表并写入80x25屏幕,但没有初始化VGA。如何执行此操作?代码: ;===DATA============================================================================================ [bits 16] [org 0x500]

我正在尝试更改此代码中的VGA。人们说我可以使用int10h,但是,我在virtualbox中遇到了一个错误。我想在这一点上设置任何类型的vga屏幕。我设法设置了Globa描述表并写入80x25屏幕,但没有初始化VGA。如何执行此操作?

代码:

;===DATA============================================================================================
[bits   16]
[org    0x500]

jmp boot

;===VARIABLES======================================================================================
gdt_start:
    dd  0
    dd  0

    dw  0xFFFF
    dw  0
    db  0
    db  10011010b
    db  11001111b
    db  0

    dw  0xFFFF
    dw  0
    db  0
    db  10010010b
    db  11001111b
    db  0
gdt_end:
GDT_loader:
    dw  gdt_end - gdt_start - 1
    dd  gdt_start

;===CODE============================================================================================
load_GDT:
    pusha
    cli
    lgdt    [GDT_loader]
    sti
    popa
    ret

boot:
    ; Initalize the GDT
    ; Setup Stacks
    cli
    mov ax, 0x0000
    mov ss, ax
    mov sp, 0xFFFF
    sti

    ; Clear segment registers
    mov ax, 00h
    mov ds, ax
    mov es, ax
    mov fs, ax
    mov gs, ax

    call load_GDT

    cli
    mov eax, cr0
    or  eax, 1
    mov cr0, eax
    jmp 08h:kernel

;===VARIABLES=======================================================================================
bootingmessage      db "Starting up", 0x00

;===DATA============================================================================================
[bits   32]
;===CODE============================================================================================
kernel:
    mov ax, 10h
    mov ds, ax
    mov es, ax
    mov ss, ax
    mov esp, 0x900000

    cli

    ;*****************
    ;Setup VGA Here
    ;*****************

    jmp $

我必须假设,当您尝试使用
int 0x10
时(在VirtualBox中)出现错误的原因是您在受保护模式下执行此操作(包括
int 0x10
在内的BIOS功能预计将在实模式下执行)。否则,它应该在VirtualBox中工作得很好

备选方案是:

  • 在引导期间设置视频模式(在切换到保护模式之前)

  • 使用virtual8086模式(在仍处于保护模式时执行实模式代码)

  • 使用仿真器或解释器(在保护模式下执行/解释实模式代码)

  • 每次更改视频模式时,请临时切换到真实模式。这是一个非常糟糕的想法(由于在未处于保护模式时接收IRQ,因此会阻止本机驱动程序正常工作)

  • 为“通用VGA”编写本机驱动程序

  • 为每个不同的视频卡编写本机驱动程序

对于所有这些选项;我得说第一个和最后一个是唯一理智的。其他的完全是浪费时间,从长远来看是没有用的——任何在引导后依赖于实模式BIOS功能的东西在现代(UEFI)计算机上都没有用;VGA是如此难看(颜色深度和分辨率极低),以至于让人眼花缭乱(并且假设“在硬件级别上100%兼容VGA,没有任何缺陷、怪癖或不兼容”这是一个相对不可靠的假设,因为实际的VGA卡已经30多年没有存在了,而VGA只是真正的视频卡出于向后兼容的目的勉强容忍的东西)


更具体地说;您的引导加载程序可能应该在引导期间设置视频模式(如果引导加载程序设计用于BIOS,则使用VBE;如果引导加载程序设计用于UEFI,则使用GOP或UGA),并告诉操作系统/内核相关详细信息(帧缓冲区地址、水平和垂直分辨率、颜色深度和像素格式、每扫描行字节数);操作系统应使用此信息提供“仅原始帧缓冲区”驱动程序(直到/除非它为特定视频卡/GPU加载本机驱动程序)。

我必须假设,当您尝试使用
int 0x10
时(在VirtualBox中)出现错误的原因是您在保护模式下执行此操作(包括
int0x10
在内的BIOS功能预计将在实模式下执行)。否则,它应该在VirtualBox中工作得很好

备选方案是:

  • 在引导期间设置视频模式(在切换到保护模式之前)

  • 使用virtual8086模式(在仍处于保护模式时执行实模式代码)

  • 使用仿真器或解释器(在保护模式下执行/解释实模式代码)

  • 每次更改视频模式时,请临时切换到真实模式。这是一个非常糟糕的主意(由于在未处于保护模式时接收IRQ,因此会阻止本机驱动程序正常工作)

  • 为“通用VGA”编写本机驱动程序

  • 为每个不同的视频卡编写本机驱动程序

对于所有这些选项,我认为第一个和最后一个选项是唯一合理的。其他选项完全是浪费时间,从长远来看是没有用的-任何在引导后依赖于实模式BIOS功能的选项在现代(UEFI)计算机上都没有用;VGA非常难看(颜色深度和分辨率极低)这让人们的眼睛流血(并假设“在硬件级别上100%兼容VGA,没有bug、怪癖或不兼容”,这是一个相对不可靠的假设,因为实际的VGA卡已经30多年没有存在了,VGA只是真正的视频卡出于向后兼容的目的勉强容忍的东西)


更具体地说,您的引导加载程序可能应该在引导期间设置视频模式(如果引导加载程序是为BIOS设计的,则使用VBE;如果引导加载程序是为UEFI设计的,则使用GOP或UGA),并将相关细节告知OS/内核(帧缓冲区地址、水平和垂直分辨率、颜色深度和像素格式、每扫描行字节数);操作系统应使用此信息提供“仅原始帧缓冲区”驱动程序(直到/除非为特定视频卡/GPU加载本机驱动程序)。

我不知道“初始化VGA”在这种情况下的含义。你的意思是?“我有一个错误。”什么错误?我不知道“初始化VGA”在这里的意思。你的意思是“我有一个错误。”什么错误?只是为了完整性:还有另一个选项(某种)-VBE3 PM入口点。如第29页所述。Linux在保护模式下使用仿真器/解释器解释实模式视频BIOS。原因很清楚:市场上有大量视频卡,最后一个选项根本不可能。我一直在开发自己的操作系统,它是u为此,选择虚拟模式。当然:如果视频模式没有改变,第一个选项是最好的。为了完整起见:还有另一个选项(类似于)-VBE3 PM入口点。如第29页所述。Linux在保护模式下使用仿真器/解释器解释实模式视频BIOS。原因很清楚:市场上有大量视频卡,最后一个选项根本不可能。我一直在开发自己的操作系统,它是u为此,请选择虚拟模式。当然:如果视频模式没有更改,则第一个选项是最好的。