【问题标题】:Print numbers diagonally in assembly在汇编中对角打印数字
【发布时间】:2017-11-20 14:30:59
【问题描述】:

我试图在汇编中对角显示 0-9,但输出将我对角打印的数字放在窗口的中间。

代码如下:

start:
mov ah, 02h 
mov cl, 0Ah ;counter (10)
mov dx, 02h
;mov bx, 02h
mov dl, 30h ;start printing 0-9
mov dh, 02h ;start row
mov al, 02h
int 21h

again:

int 10h
int 21h
;add dx, 01h
inc dh
inc dx
inc al

loop again
mov ax, 4c00h
int 21h

输出应该是:

0
  1
    2
      3
        4
          5
            6
              7
                8 
                  9

当前输出打印,但在窗口的中间。我尝试添加一个新寄存器bh,并在执行文件时使用它将光标放在当前位置。如何从光标开始显示它?我应该把它放在一个循环上并增加寄存器ah 吗?

【问题讨论】:

  • 先打印回车和换行符(CR + LF, ascii 10 和 13),这会将光标移动到下一行的第一个位置
  • 那个或者如果有熟vs生的选项。在 pc/dos 世界中,cooked 意味着 0x0A 变成 0x0D 0x0A,否则你必须自己做,我假设这个系统调用你需要自己做。

标签: assembly x86-16 tasm dosbox


【解决方案1】:

您当前的程序失败,因为您可怕地混合了 2 个系统函数,它们恰好具有相同的函数编号 02h,但期望在 DL 寄存器中接收完全不同的信息。 DOS OutputCharacter 函数需要一个字符代码,您将其设置为 48,但 BIOS SetCursor 函数将解释与列相同的值 48。这就是结果显示在屏幕中间的原因!

既然你说你想从当前光标位置开始,在程序开始时它几乎总是在屏幕的左边缘,所以根本不需要设置光标位置。

    mov     ah, 02h
    mov     dl, "0"
Next:
    push    dx          ;Preserve current character
    int     21h
    mov     dl, " "     ;Your desired output shows this space?
    int     21h
    mov     dl, 10      ;Linefeed moves the cursor 1 line down
    int     21h
    pop     dx          ;Restore current character
    inc     dl
    cmp     dl, "9"
    jbe     Next

您可以通过查看递增的DL 寄存器中的值来决定是否循环返回,而不是使用单独的计数器。


请注意,您使用了依赖于CX 寄存器的loop 指令,但您只初始化了它的下半部分CL!这通常是程序崩溃的原因。


编辑

鉴于 DOSBox 在被要求显示字符 10 时会发出回车和换行(在 this comment by Michael Petch 中引起了我的注意),我编写了下一个小程序,我在最新的 DOSBox 0.74 版本中测试了它的准确性。

    ORG     256          ;Create .COM program

    mov     ah, 02h      ;DOS.DisplayCharacter
    mov     dx, "0"      ;DH is spaces counter, DL is current character
    jmps    First        ;Character "0" has no prepended spaces!
Next:
    push    dx           ;(1)
    mov     dl, " "
Spaces:
    int     21h
    dec     dh
    jnz     Spaces
    pop     dx           ;(1)
First:
    int     21h          ;Display character in DL
    push    dx           ;(2)
    mov     dl, 10       ;Only on DOSBox does this do Carriage return AND Linefeed !
    int     21h
    pop     dx           ;(2)
    add     dx, 0201h    ;SIMD : DH+2 and DL+1
    cmp     dl, "9"
    jbe     Next

    mov     ax, 4C00h    ;DOS.TerminateWithExitcode
    int     21h

【讨论】:

  • 问题被标记为 DOSBox。好奇你是否在那个环境中测试过它(使用股票 DOSBox 模拟器)?据我所知,未打补丁的 DOSBox 会将换行打印为 CRLF(显然是设计上的缺陷),所以这个答案不会对角打印。当运行真实版本的 DOS(甚至在 DOSBox 中)时,您的代码当然可以工作。
  • @MichaelPetch 你是对的。我自己测试了一下,发现 10 显然意味着 13 + 10 对于 DOSBox。这次我添加了一个新的解决方案并进行了验证!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-10-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-25
  • 1970-01-01
相关资源
最近更新 更多