【问题标题】:How do I solve "Assuming data segment is 32-bit" in TASM如何解决 TASM 中的“假设数据段是 32 位”
【发布时间】:2019-01-19 13:09:49
【问题描述】:

我在下面有这个程序,它使用 DOSBox 计数到 100。 它与 .286 完美配合,但我想知道如何使这项工作与 .386 配合使用。

.286
.model small
setCurPos macro x,y
    pusha
    mov ah, 02h
    mov bh, 0
    mov dl, x
    mov dh, y
    int 10h
    popa    
endm

writeChar macro char,color,ctr
    pusha 
    mov ah, 9
    mov al, char
    mov bh, 0
    mov bl, color
    mov cx, ctr
    int 10h
    popa
endm

delay macro
    mov cx, 0fh
    mov dx,4240h
    mov ah,86h
    int 15h
endm

.stack 100h
.data 
percentage db 0
ones       db ?
tens       db ?
.code
org 100
main proc far
    mov ax, @data
    mov ds, ax
    mov es, ax

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

    jmp count

    to_printHundred:
    jmp printHundred

    count:
    delay
    cmp percentage, 64h
    je  to_printHundred
    cmp percentage, 0ah
    jae printTens

    ;printOnes
    mov al, percentage
    add al, 30h
    mov ones, al
    setCurPos 10, 10
    writeChar ones, 0fh, 1
    inc percentage
    jmp count

    printTens:
    xor ax, ax
    mov bx, 0ah
    mov al, percentage
    div bl
    add al, 30h
    add ah, 30h
    mov tens, al
    mov ones, ah
    setCurPos 10,10
    writeChar tens,0fh,1
    setCurPos 11,10
    writeChar ones,0fh,1
    inc percentage
    jmp count

    printHundred:
    mov tens, 31h
    mov ones, 30h
    setCurPos 10,10
    writeChar tens,0fh,1
    setCurPos 11,10
    writeChar ones,0fh,2

    mov ah, 4ch
    int 21h
endp
end main

每当我使用延迟时,它都会冻结并输出非法读/写。当程序真的很大时,必须一直为条件跳转创建继电器很糟糕。

【问题讨论】:

  • TASM 可以为您生成超出 -128 到 127 范围的条件跳转所需的代码,如果您在文件顶部添加 JUMPS 指令作为第一行。
  • 谢谢,有帮助!我还交换了 .data 和 .code。它极大地减少了跳跃错误。最后,我还注意到在文件顶部添加跳转指令会消耗大量内存,还必须将模型从小切换到小。
  • 所以在编译时,它似乎完全没有问题,但在链接时,我想出了修复溢出错误?我该如何解决?

标签: assembly x86-16 tasm


【解决方案1】:

每当我使用延迟时,它都会冻结并输出非法读/写。当程序真的很大时,必须一直为条件跳转创建中继是很糟糕的。

这是 DOSBox 的一个问题,它在 int 15h AH=86h 函数上出错。
我通过编程基于 BIOS 计时器滴答声的延迟机制来解决这个问题。您可以在a-low-tech-approach-to-measuring-game-speed找到所有详细信息

我的第一段与您的问题描述相符:

在开发游戏时,我需要一个延迟例程,能够实现从 0.5 秒到几毫秒不等的延迟。显而易见的选择是在 int 15h 上使用 BIOS 延迟功能 86h。在真正的真实地址模式环境中,它可以正常工作,但我看到 像 DOSBox 这样的模拟器会搞砸事情。大量非法读写。所以我不得不想出另一个解决方案。


如果您担心程序大小,那么您可能希望将这些宏更改为子例程。每次调用宏时,其所有代码都会插入到程序中,而子例程会被编码一次,并且仅由 call 指令调用多次。


.code
org 100
main proc far
    mov ax, @data
    mov ds, ax
    mov es, ax

你确定你的.model small 程序需要这个org 100 指令吗?

如果作为indicated in a comment,您已更改为.model tiny,则ORG 宁愿必须是org 256。

【讨论】:

  • 一切都好,子程序成功了。谢谢你的详细回答。将来我会练习实现更多的子程序和过程,而不是宏。
猜你喜欢
  • 2011-09-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-11
  • 2015-08-20
  • 2012-03-13
相关资源
最近更新 更多