装配 x86-16 中的模式 X,为什么平面 1 未打印,而所有其他平面的顺序不正确?

2024-03-12

我正在 DosBox 0.74 上的 TASM 3.0 中写入,并且我正在尝试写入Mode x https://en.wikipedia.org/wiki/Mode_X(调整了13小时,无束缚模式 13 http://www.brackeen.com/vga/unchain.html),但是你可以在图像中看到,它不太正确。 似乎平面 1(第二个平面)根本没有打印,并且所有其他平面的顺序都不正确。 我知道这里的代码效率低下,但我想让它工作然后清理它。

proc showBMP
    push cx
    mov ax, 0A000h
    mov es, ax
    mov cx, [BMPHeight]
    mov ax, [BMPWidth]
    xor dx, dx
    mov si, 4
    div si
    mov bp, dx
    mov dx, [BMPX]
    showBMP_nextLine:
        call VGAPlaneStartBMP
        push cx
        push dx
        mov di, cx
        add di, [BMPY]
        mov cx, di
        shl cx, 6
        shl di, 8
        add di, cx
        add di, dx
        mov ah, 3fh
        mov cx, [BMPWidth]
        add cx, bp
        mov dx, offset BMPMaxLine
        int 21h
        cld
        mov cx, [BMPWidth]
        mov si, offset BMPMaxLine
        showBMP_nextLine_movsbLoop:
            push cx
            push di
            shr di, 2
            mov cl, [ds:si]
            mov [es:di], cl
            inc [VGAPlane]
            inc si
            pop di
            inc di
            pop cx
            call VGAPlaneSelect
        loop showBMP_nextLine_movsbLoop
        pop dx
        pop cx
    loop showBMP_nextLine
    pop cx
    ret
endp showBMP

在这里您可以看到打印位图文件的过程,该过程在 chain-4 模式 13 上完美运行。

  • BMPHeight - 顾名思义就是图片的高度
  • BMP宽度 - 相同
  • BMPX - 图片在屏幕上开始的位置(x 坐标)
  • BMPY - 相同但 Y 坐标
  • BMPMaxLine - 320 的数组用作缓冲区
  • VGAPlane - 0/1/2/3 平面之一
  proc VGAPlaneStartBMP
       push ax
       push bx
       mov ax, [BMPX]
       mov bx, offset PlaneByX
       add bx, ax
       mov al, [bx]
       mov [VGAPlane], al
       pop bx
       pop ax
       call VGAPlaneSelect
       ret
   endp VGAPlaneStartBMP

此过程对于打印的每一行,通过行的起始 x 选择平面:

  • PlaneByX - MAX_WIDTH / NUMBER_OF_PLANES 重复 (PLANES),重置

  • MAX_WIDTH 为 320,NUMBER_OF_PLANES 为 4,PLANES 为 0, 1, 2, 3,

proc VGAPlaneSelect
        push ax
        push dx
        mov al, 02h
        mov dx, 03C4h
        out dx, al
        VGAPlaneSelect_start:
        cmp [VGAPlane], 0
        jne VGAPlaneSelect_0
            mov al, 0h
            jmp VGAPlaneSelect_end
        VGAPlaneSelect_0:
        cmp [VGAPlane], 1
        jne VGAPlaneSelect_1
            mov al, 1h
            jmp VGAPlaneSelect_end
        VGAPlaneSelect_1:
        cmp [VGAPlane], 2
        jne VGAPlaneSelect_2
            mov al, 4h
            jmp VGAPlaneSelect_end
        VGAPlaneSelect_2:
        cmp [VGAPlane], 3
        jne VGAPlaneSelect_3
            mov al, 8h
            jmp VGAPlaneSelect_end
        VGAPlaneSelect_3:
            mov [VGAPlane], 0
            jmp VGAPlaneSelect_start
        VGAPlaneSelect_end:
        inc dx
        out dx, al
        pop dx
        pop ax
        ret
    endp VGAPlaneSelect

最后这个代码是在选择飞机时。


感谢 Fuz 找到答案,感谢 Jonathon Reinhart 让我的问题更加清晰。 在VGAPlaneSelect过程中,al值是0x3c5 VGA地址的输出,应该是2^(你想要选择的平面),对于平面0 2^0它应该是1,我写了0

so:

        cmp [VGAPlane], 0
        jne VGAPlaneSelect_0
            mov al, 1h
            jmp VGAPlaneSelect_end
        VGAPlaneSelect_0:

更好的方法来做到这一点VGAPlaneSelect程序是:

    proc VGAPlaneSelect
        push ax
        push dx
        push cx
        mov al, 02h
        mov dx, 03C4h
        out dx, al
        VGAPlaneSelect_start:
        mov ax, 1
        mov cl, [VGAPlane]
        shl ax, cl
        cmp [VGAPlane], 4
        jne VGAPlaneSelect_end
            mov [VGAPlane], 0
            jmp VGAPlaneSelect_start
        VGAPlaneSelect_end:
        mov dx, 03C5h
        out dx, al
        pop cx
        pop dx
        pop ax
        ret
    endp VGAPlaneSelect
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

装配 x86-16 中的模式 X,为什么平面 1 未打印,而所有其他平面的顺序不正确? 的相关文章

  • 如何使用 Java2D 图形正确绘制点间距很近的粗线?

    我正在尝试使用 Java2D 绘制地图 当我的地图缩小时 我的道路上充满了绘画制品 这是绘制完整的美国州时屏幕的一小部分 放大后 这是一段相似的路段 使用的线条样式是一条蓝色实线 其宽度缩放为相当于 2 个像素 我尝试了各种渲染提示和行连接
  • RAM 存储二进制数和汇编语言的冒泡排序

    我必须使用 ARM v7 执行一个例程 在 RAM 内存中存储 10 个二进制数 然后使用冒泡排序对这些数字从高到低进行排序 我应该如何开始 func bubbleSortAscendingU32 ldr r3 r0 4 mov r1 9
  • 逆向工程的汇编语言[关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 将 GCC 内联汇编与采用立即值的指令结合使用

    问题 我正在为 ARM Cortex M3 处理器开发定制操作系统 为了与我的内核交互 用户线程必须生成 SuperVisor Call SVC 指令 以前称为 SWI 用于软件中断 该指令在ARM ARM中的定义是 这意味着该指令需要即时
  • FASM 是否使用 Intel 语法?

    我尝试在 FASM 中编译以下代码 mov DWORD PTR ebp 4 1234567 它给了我一个 无效表达式 错误 但是以下代码有效 mov DWORD ebp 4 1234567 那么 FASM 是否使用 Intel 语法 我假设
  • “mov offset(%rip),%rax”有什么作用?

    Does rax获取偏移量加上这条指令的地址 还是下一条指令的地址 从微代码的角度来看 如果答案是下一条指令可能会更容易 下一个 这是 x86 上的一般规则 另请参阅分支 在 Intel 手册第 2 卷第 2 2 1 6 RIP 相对寻址部
  • 使用汇编器 8086 显示表的总和

    我正在编写一些代码 允许我对表进行求和 然后使用汇编语言显示其结果 这是我到目前为止所想到的 data segment tab db 9 dup 3 5 8 4 7 1 6 7 0 resultat db data ends code se
  • 我如何使其解密而不是加密?

    想知道如何从加密代码中获取此代码并使用相同的代码来创建解密 我知道这意味着我必须反转一些指令并重新排序 但我无法弄清楚哪些指令需要重新排序 哪些不需要 编辑 这是完整的函数 可以让事情变得更清晰一些 对堆栈溢出非常陌生 因此对于任何混淆表示
  • 使用拼凑将组合子图(拼凑?)注释为单个图

    我试图弄清楚如何注释组合拼凑物 就好像它们是单独的图一样 我有一个由三个组合图和另一个单个图组成的拼凑而成 最终的复合图是顶部的第一个拼凑物和底部的单独图 我没有问题得到我想要的布局 但是当我使用plot annotation 它为每个图提
  • 自定义键盘中断处理程序

    我正在尝试编写一个简单的程序 将标准键盘中断替换为自定义的键盘中断 以减少变量 但是 如果不调用旧处理程序 它就无法工作 这是我的中断处理程序 handler proc push ax push di dec EF pushf when t
  • MIPS 在程序中使用 $s0... 等注册并最终恢复它是否优雅

    我在 MIPS 教程中读到 只有寄存器 s0 s7 在过程调用中被保留 但我认为 也许我错了 创建有副作用的程序并不优雅 我认为程序应该只更改 v0 v1 寄存器和堆栈 如果需要的话 我是对的吗 所以我认为在我的程序中我只能使用 t0 t9
  • x86 Assembly:很难找到无限循环挑战的想法

    我打算和我的朋友们进行一场类似于 corewars 的比赛 我们使用与原始游戏相同的内存网格 在游戏中 我们每个人都应该写一个 保险箱 它是一个不超过 25 行的无限循环 每个 安全 都有一个技巧或代码可以停止循环 从而破坏 安全 例如 S
  • 在 Mathematica 中使用图形进行渐变填充

    我如何使用以下内容创建Rectangle in Graphics Using Polygon 你可以 Graphics EdgeForm Black Polygon 0 0 3 0 3 1 0 1 VertexColors gt White
  • NOP 雪橇如何工作?

    我找不到回答这个问题的好来源 我知道 nop sled 是一种用于规避缓冲区溢出攻击中堆栈随机化的技术 但我无法理解它是如何工作的 有什么简单的例子可以说明这种方法 128 字节 nop sled 等术语是什么意思 有些攻击包括使程序跳转到
  • I 类型指令的 MIPS 周期数 (addi)

    So on https en wikipedia org wiki Cycles per instruction https en wikipedia org wiki Cycles per instruction它说 对于多周期MIPS
  • 从色调 0 到 360 的 SVG 线性渐变

    source elv1s ru http elv1s ru files svg gradient hue png 做这样的渐变的正确方法是什么 我试过this SVG http elv1s ru files svg gradient hue
  • 如何在汇编程序中使用 C 库?

    我想知道如何用汇编语言编写文本编辑器 但现代操作系统需要 C 库 特别是对于它们的窗口系统 我找到了这个page http pengu1n is programmer com posts 8304 html 这对我有很大帮助 但我想知道是否
  • 现代 x86 硬件不能将单个字节存储到内存中吗?

    说到 C 的并发内存模型 Stroustrup 的C 编程语言 第 4 版 第 1 节 41 2 1 说 就像大多数现代硬件一样 机器无法加载或存储小于单词的任何内容 然而 我的 x86 处理器已经有几年的历史了 它可以并且确实存储小于单词
  • g++ 内联汇编括号中不匹配

    g 向我抱怨以下代码中缺少括号 1 2 3 v v v asm volatile inb 1 0 a result Nd portnumber 1 2 3 正如您所看到的 括号是匹配
  • 在DOS中创建带有echo的文件而不插入回车符

    我想在 DOS 中的 CIFS 挂载上创建一个新文件 如果我做 echo hello gt foo txt hello 的末尾会有一个 CR 如何使用 echo 在 DOS cmd 中创建文件而不自动附加 CR 它导致 samba 和我的

随机推荐