【问题标题】:writing directly to video memory直接写入显存
【发布时间】:2018-05-19 22:25:27
【问题描述】:

我听说 int 10h, ah = 0Ch 很慢,为了获得合理的速度,我需要进入内存并将值放入我想要的像素中,我将视频模式设置为 @987654322 @ 与int 10h。 更改视频模式的调用:

mov ah , 0
mov al , 13h
int 10h

这是我为了在给定坐标中放置一个像素而编写的程序:

drawFaster proc
    ; bp + 2 - row (dx)
    ; bp + 4 - column (cx)
    ; bp + 6 - color
    mov bp , sp
    pushad
    mov ax , 0A000h - presumably the memory address of the screen
    mov es , ax
    mov ax , [bp + 2]
    mov bx , [bp + 4]
    mov cx , 320
    mul cx

    add ax , bx
    mov di , ax
    mov ax , [bp + 6]

    mov [es:di] , al 

    popad
    ret 6
endp

调用函数的代码:

    push bp
    mov ax , 30
    push ax
    mov cx , 50
    push cx
    mov dx , 50
    push dx
    call drawFaster
    pop bp

但由于某种原因,这不会产生任何结果,我不知道内存地址是否不正确或是否有其他问题。我需要你的帮助。谢谢!

奇怪的是下面这段代码有效

mov ax , 0A000H
mov es , ax
mov [es:0] , 30

但是下面这段代码没有:

mov ax , 0A000H
mov bx , 0
mov es , ax
mov [es:bx] , 30

【问题讨论】:

  • 写入显存的代码对我来说是正确的。这里有几件事要检查: 1) 检查参数是否正确传递。 cmets 提到了寄存器和堆栈位置。如果像素值 [bp+6] 为 0,则为黑色。 2) 你确定调色板是按照你想要的方式设置的吗?我猜当您设置视频模式时,BIOS 会将调色板设置为默认值,但我还没有找到确认。
  • 代码上的几个附加 cmets:1) 它不恢复 bp,在大多数调用约定中假定它被保留。 2)请不要使用pusha;如果您使用典型的调用约定,则仅保存您需要的寄存器,在本例中为 bx、di 和 bp。您可以很容易地避免使用 bx,以避免必须保留它。我认为 es 可能也应该保留。
  • 您确定该地址吗?请参阅this,这表明它是 B8000。
  • @DavidWohlferd :bp+6 是像素的颜色(8 位)。我假设他使用的是 8 位颜色的 320x200。
  • @PeterCordes 是的,但如果他通过“黑色”,那么一切都会“工作”,但仍然“没有结果”。

标签: assembly memory x86-16 vga


【解决方案1】:

我找到了一种解决方法,但它可能不是最好的方法,而不是使用es(因为它不起作用)

我把数据段的地址改成了0A000H

然后我用mov [di] , al 更改像素,它就可以工作了!

但如果你正在尝试这样做,请务必将数据段的地址移回原来的位置。

我的功能处于工作状态,如果有人感兴趣的话:

drawFaster proc
    ; bp + 2 - row (dx)
    ; bp + 4 - column (cx)
    ; bp + 6 - color
    mov bp , sp ; changing bp to access the stack segment
    ; pushing the values to not lose them in the process of calling the function
    push ax
    push bx
    push cx
    push dx
    mov ax, 0A000h ; 0A000h is the video memory address (for some video modes like 13h)
    mov ds , ax
    mov ax , [bp + 2] ; getting the row ( Y )
    mov bx , [bp + 4] ; getting the column ( X )
    mov cx , 320 ; multiplying the row by 320 to get the offset, and then adding the column
    mul cx

    add ax , bx
    mov di , ax
    mov ax , [bp + 6] ; getting the desired color to paint the pixel in 
    mov [di] , al ; changing the color of the chosen pixel with the desired color
    ; changing the data segment's address back to its original state 
    ; VERY CRUCIAL PLEASE DON'T MISS THIS IF YOU DO IT THE SAME WAY
    mov ax , @data
    mov ds, ax
    ; changing the values back to what they were
    pop dx
    pop cx
    pop bx
    pop ax
    ret 6
endp

【讨论】:

    猜你喜欢
    • 2023-03-13
    • 2011-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-04
    • 1970-01-01
    • 1970-01-01
    • 2011-10-31
    相关资源
    最近更新 更多