【问题标题】:Can't access all the screen bytes in ASM x86 protected mode在 ASM x86 保护模式下无法访问所有屏幕字节
【发布时间】:2020-03-11 01:59:28
【问题描述】:

为什么我无法在 vesa 模式下访问所有像素?

mov ax, 0x4F02;                 // vesa video mode
mov bx, 0x0101;                 // mode 640x480 256 colors

int 0x10;                       // video interupter

我直接在屏幕上绘图(在保护模式下):

mov edi, 0x0A0000
add edi, 80000
mov al,0x0F      ; the color of the pixel
mov [edi], al

在实模式下:

mov ax, 0xA000; video adress
mov es, ax; segment address to es

mov di, 1200; pixel adress x + ( y * width )
mov al, 0x25; pixel colour
mov [es:di], al;

在 13h 模式下,我可以在整个屏幕上绘制,但在 vesa 中,我只能在 +/- line(y) 100 之前绘制

【问题讨论】:

  • 因为你没有启用线性帧缓冲所以你仍然只有一个 64k 的窗口。
  • 我该怎么做?
  • 谢谢,我完成后会发布正确的代码。
  • 仅供参考,mov byte [0x0A0000 + 80000], 0x0f 相当于您的 4 条指令序列(除了不在寄存器中保留值。尤其是运行时 add 指令与 mov edi, 0x0A0000 + 80000[edi + 80000] 相比似乎毫无意义/跨度>

标签: assembly x86 nasm vga memory-segmentation


【解决方案1】:

为什么我无法在 vesa 模式下访问所有像素?

最初(由于实模式的限制以及原始视频卡不需要更多),视频卡被分配了两个 64 KiB 物理内存区域(从 0x000A0000 到 0x000AFFFF,从 0x000B0000 到 0x000BFFFF)。

当视频卡开始支持更好的视频模式(更多像素和更多位/像素)时,帧缓冲区不适合 64 KiB 区域;所以显卡开始做一个叫做“银行切换”的丑陋黑客来解决这个问题。基本上;您可以选择将哪个 64 KiB 帧缓冲区映射到物理地址空间的传统 64 KiB 区域。

当显卡开始支持更好的视频模式时,组切换开始变得混乱(尤其是对于 24 位视频模式,同一像素的不同部分可以在不同组中),并且随着视频 RAM 变得更快,组切换(使用慢速 IO 端口)没有,银行切换成为性能问题。同时,CPU 支持更大的物理地址大小(例如 4 GiB 而不是原来的 1 MiB),整个缓慢的乱七八糟的混乱似乎更加愚蠢。修复不同的视频卡开始在不同的物理地址提供它们的整个帧缓冲区(使用专有的非标准扩展);不久之后,VBE 添加了一个标准 API,软件可以使用该 API 来控制专有的非标准扩展。这被称为“线性帧缓冲区”(LFB)。

在实践中;这意味着:

  • 对于 VBE 1,您必须使用存储区切换来访问超过 64 KiB 的帧缓冲区。 注意:理论上,对于某些显卡,可以同时配置两个 64 KiB 区域,使其看起来像一个 128 KiB 区域;当视频模式的帧缓冲区大于 64 KiB 且小于 128 KiB 时,这有助于避免 bank 切换。

  • 对于 VBE 2 及更高版本,您可以选择使用库切换或 LFB。在这种情况下,您必须检查视频模式是否支持LFB,然后在设置模式时通过设置标志告诉VBE您要使用LFB,并从VBE的模式中获取LFB的地址(不会位于0x000A0000)信息结构。

【讨论】:

    【解决方案2】:

    此代码配置VBE模式,并在屏幕上绘制一个像素(您可以使用LFB在所有屏幕上绘制):

    vbe_info:
    
        .signature db "VBE2";   // must be "VESA" to indicate valid VBE support
        .version resw 1;            // VBE version; high byte is major version, low byte is minor version
        .oem resd 1;            // segment:offset pointer to OEM
        .capabilities resd 1;       // bitfield that describes card capabilities
        .video_modes resd 1;        // segment:offset pointer to list of supported video modes
        .video_memory resw 1;       // amount of video memory in 64KB blocks
        .software_rev resw 1;       // software revision
        .vendor resd 1;         // segment:offset to card vendor string
        .product_name resd 1;       // segment:offset to card model name
        .product_rev resd 1;        // segment:offset pointer to product revision
        .reserved resb 222;     // reserved for future expansion
        .oem_data resb 256;     // OEM BIOSes store their strings in this area
    
    mode_info:
    
        .attributes resw 1;     // deprecated, only bit 7 should be of interest to you, and it indicates the mode supports a linear frame buffer.
        .window_a resb 1;           // deprecated
        .window_b resb 1;           // deprecated
        .granularity resw 1;        // deprecated; used while calculating bank numbers
        .window_size resw 1;
        .segment_a resw 1;
        .segment_b resw 1;
        .win_func_ptr resd 1;       // deprecated; used to switch banks from protected mode without returning to real mode
        .pitch resw 1;          // number of bytes per horizontal line
        .width resw 1;          // width in pixels
        .height resw 1;         // height in pixels
        .w_char resb 1;         // unused...
        .y_char resb 1;         // ...
        .planes resb 1;
        .bpp resb 1;            // bits per pixel in this mode
        .banks resb 1;          // deprecated; total number of banks in this mode
        .memory_model resb 1;
        .bank_size resb 1;      // deprecated; size of a bank, almost always 64 KB but may be 16 KB...
        .image_pages resb 1;
        .reserved0 resb 1;
    
        .red_mask resb 1;
        .red_position resb 1;
        .green_mask resb 1;
        .green_position resb 1;
        .blue_mask resb 1;
        .blue_position resb 1;
        .reserved_mask resb 1;
        .reserved_position resb 1;
        .direct_color_attributes resb 1;
    
        .framebuffer resd 1;        // physical address of the linear frame buffer; write here to draw to the screen
        .off_screen_mem_off resd 1;
        .off_screen_mem_size resw 1;    // size of memory in the framebuffer but not being displayed on the screen
        .reserved1 resb 206;
    
    enable_vesa:
    
    vbe_get_info:
    
        mov ah, 4Fh;        Super VGA support
        mov al, 00h;        Return Super VGA information
        mov di, vbe_info;   Pointer to buffer
    
        int 0x10;
    
        cmp ax, 0x4F                ; BIOS doesn't support VBE?
        jne error
    
    get_mode_info:
    
        mov ax, 4F01h;        Return mode information
        mov cx, 0x101;[vbe_info.video_modes]; first mode
        mov di, mode_info;  Pointer to buffer
    
        int 0x10;
    
        cmp ax, 0x4F                ; BIOS doesn't support VBE?
        jne error
    
    set_mode:
    
        mov ah, 0
        mov ax, 0x4F02
        mov ebx, [vbe_info.video_modes]; estore de modes pointer at ebx to can access as a adress
        mov bx, [ebx+8]; 8/2 = 4th mode in the mode array!!!!!!!
    
        int 0x10
    
    draw:
    
        ;Assume first window is valid 
        mov ax, WORD [es:mode_info + 08h]
        mov es, ax
    
        ;Example of how to change the window 
        mov ax, 4f05h
        xor bx, bx
        mov dx, 5       ;This is granularity units
        int 10h
    
        ;fist atempt
        mov edi, [mode_info.framebuffer];   framebuffer
        add edi, 180050;                        pixel_offset = y * pitch + ( x * ( bpp/8 )) + framebuffer;
        mov al,0x0F;                        the color of the pixel
        mov [edi], al
    
        mov si, msg;
        call print
    
        jmp $
    
    msg db "finish", 0
    

    【讨论】:

      猜你喜欢
      • 2023-03-24
      • 2021-10-12
      • 1970-01-01
      • 2016-04-06
      • 1970-01-01
      • 1970-01-01
      • 2011-11-21
      • 1970-01-01
      • 2016-02-04
      相关资源
      最近更新 更多