在组合件中按对角线打印数字



我试图在汇编中对角显示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上吗?

您当前的程序失败是因为您可怕地混合了两个碰巧具有相同函数号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时同时发出Carriage return和Linefeed(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

最新更新