【问题标题】:How can i print characters diagonal with loop in assembly如何在汇编中使用循环打印对角线字符
【发布时间】:2017-10-30 20:31:43
【问题描述】:
CODE SEGMENT
ASSUME CS:CODE
START:  

MOV AH,06h ;INT 10,6
MOV AL,00h ;number of lines to scroll, previous lines are
;blanked, if 0 or AL > screen size, window is blanked
MOV CH,00h ;row of upper left corner of scroll window
MOV CL,00h ;column of upper left corner of scroll window
MOV DH,24h ;row of lower right corner of scroll window
MOV DL,79h ;column of lower right corner of scroll window
MOV BH,07h ;attribute to be used on blank line
INT 10h



MOV AH,02H
MOV BH,00H
MOV DH,01H
MOV DL,03H
INT 10H
MOV AH,02h
MOV DL,2Ah
INT 21h

MOV AH,02H
MOV BH,00H
MOV DH,02H
MOV DL,06H
INT 10H
MOV AH,02h
MOV DL,2Ah
INT 21h

MOV AH,02H
MOV BH,00H
MOV DH,03H
MOV DL,0AH
INT 10H
MOV AH,02h
MOV DL,2Ah
INT 21h

MOV AH,02H
MOV BH,00H
MOV DH,04H
MOV DL,0DH
INT 10H
MOV AH,02h
MOV DL,2Ah
INT 21h

MOV AH,02H
MOV BH,00H
MOV DH,05H
MOV DL,10H
INT 10H
MOV AH,02h
MOV DL,2Ah
INT 21h

MOV AH,02H
MOV BH,00H
MOV DH,06H
MOV DL,14H
INT 10H
MOV AH,02h
MOV DL,2Ah
INT 21h

MOV AH,02H
MOV BH,00H
MOV DH,07H
MOV DL,17H
INT 10H
MOV AH,02h
MOV DL,2Ah
INT 21h

MOV AH,02H
MOV BH,00H
MOV DH,08H
MOV DL,1AH
INT 10H
MOV AH,02h
MOV DL,2Ah
INT 21h

MOV AH,02H
MOV BH,00H
MOV DH,09H
MOV DL,1EH
INT 10H
MOV AH,02h
MOV DL,2Ah
INT 21h

MOV AH,02H
MOV BH,00H
MOV DH,0AH
MOV DL,21H
INT 10H
MOV AH,02h
MOV DL,2Ah
INT 21h

MOV AH,02H
MOV BH,00H
MOV DH,0BH
MOV DL,24H
INT 10H
MOV AH,02h
MOV DL,2Ah
INT 21h

MOV AH,02H
MOV BH,00H
MOV DH,0CH
MOV DL,28H
INT 10H
MOV AH,02h
MOV DL,2Ah
INT 21h

MOV AH,02H
MOV BH,00H
MOV DH,0DH
MOV DL,2BH
INT 10H
MOV AH,02h
MOV DL,2Ah
INT 21h

MOV AH,02H
MOV BH,00H
MOV DH,0EH
MOV DL,2EH
INT 10H
MOV AH,02h
MOV DL,2Ah
INT 21h

MOV AH,02H
MOV BH,00H
MOV DH,0FH
MOV DL,32H
INT 10H
MOV AH,02h
MOV DL,2Ah
INT 21h

MOV AH,02H
MOV BH,00H
MOV DH,10H
MOV DL,35H
INT 10H
MOV AH,02h
MOV DL,2Ah
INT 21h

MOV AH,02H
MOV BH,00H
MOV DH,11H
MOV DL,38H
INT 10H
MOV AH,02h
MOV DL,2Ah
INT 21h

MOV AH,02H
MOV BH,00H
MOV DH,12H
MOV DL,3CH
INT 10H
MOV AH,02h
MOV DL,2Ah
INT 21h

MOV AH,02H
MOV BH,00H
MOV DH,13H
MOV DL,3FH
INT 10H
MOV AH,02h
MOV DL,2Ah
INT 21h

MOV AH,02H
MOV BH,00H
MOV DH,14H
MOV DL,42H
INT 10H
MOV AH,02h
MOV DL,2Ah
INT 21h

MOV AH,02H
MOV BH,00H
MOV DH,15H
MOV DL,46H
INT 10H
MOV AH,02h
MOV DL,2Ah
INT 21h

MOV AH,02H
MOV BH,00H
MOV DH,16H
MOV DL,49H
INT 10H
MOV AH,02h
MOV DL,2Ah
INT 21h

MOV AH,02H
MOV BH,00H
MOV DH,17H
MOV DL,4CH
INT 10H
MOV AH,02h
MOV DL,2Ah
INT 21h

MOV AH,02H
MOV BH,00H
MOV DH,18H
MOV DL,50H
INT 10H
MOV AH,02h
MOV DL,2Ah
INT 21h


;-------------------------------------------------------




MOV AH,02H
MOV BH,00H
MOV DH,01H
MOV DL,4DH
INT 10H
MOV AH,02h
MOV DL,2Ah
INT 21h

MOV AH,02H
MOV BH,00H
MOV DH,02H
MOV DL,4AH
INT 10H
MOV AH,02h
MOV DL,2Ah
INT 21h

MOV AH,02H
MOV BH,00H
MOV DH,03H
MOV DL,46H
INT 10H
MOV AH,02h
MOV DL,2Ah
INT 21h

MOV AH,02H
MOV BH,00H
MOV DH,04H
MOV DL,43H
INT 10H
MOV AH,02h
MOV DL,2Ah
INT 21h

MOV AH,02H
MOV BH,00H
MOV DH,05H
MOV DL,40H
INT 10H
MOV AH,02h
MOV DL,2Ah
INT 21h

MOV AH,02H
MOV BH,00H
MOV DH,06H
MOV DL,3CH
INT 10H
MOV AH,02h
MOV DL,2Ah
INT 21h

MOV AH,02H
MOV BH,00H
MOV DH,07H
MOV DL,39H
INT 10H
MOV AH,02h
MOV DL,2Ah
INT 21h

MOV AH,02H
MOV BH,00H
MOV DH,08H
MOV DL,36H
INT 10H
MOV AH,02h
MOV DL,2Ah
INT 21h

MOV AH,02H
MOV BH,00H
MOV DH,09H
MOV DL,32H
INT 10H
MOV AH,02h
MOV DL,2Ah
INT 21h

MOV AH,02H
MOV BH,00H
MOV DH,0AH
MOV DL,2FH
INT 10H
MOV AH,02h
MOV DL,2Ah
INT 21h

MOV AH,02H
MOV BH,00H
MOV DH,0BH
MOV DL,2CH
INT 10H
MOV AH,02h
MOV DL,2Ah
INT 21h



MOV AH,02H
MOV BH,00H
MOV DH,0DH
MOV DL,25H
INT 10H
MOV AH,02h
MOV DL,2Ah
INT 21h

MOV AH,02H
MOV BH,00H
MOV DH,0EH
MOV DL,22H
INT 10H
MOV AH,02h
MOV DL,2Ah
INT 21h

MOV AH,02H
MOV BH,00H
MOV DH,0FH
MOV DL,1EH
INT 10H
MOV AH,02h
MOV DL,2Ah
INT 21h

MOV AH,02H
MOV BH,00H
MOV DH,10H
MOV DL,1BH
INT 10H
MOV AH,02h
MOV DL,2Ah
INT 21h

MOV AH,02H
MOV BH,00H
MOV DH,11H
MOV DL,18H
INT 10H
MOV AH,02h
MOV DL,2Ah
INT 21h

MOV AH,02H
MOV BH,00H
MOV DH,12H
MOV DL,14H
INT 10H
MOV AH,02h
MOV DL,2Ah
INT 21h

MOV AH,02H
MOV BH,00H
MOV DH,13H
MOV DL,11H
INT 10H
MOV AH,02h
MOV DL,2Ah
INT 21h

MOV AH,02H
MOV BH,00H
MOV DH,14H
MOV DL,0EH
INT 10H
MOV AH,02h
MOV DL,2Ah
INT 21h

MOV AH,02H
MOV BH,00H
MOV DH,15H
MOV DL,0AH
INT 10H
MOV AH,02h
MOV DL,2Ah
INT 21h

MOV AH,02H
MOV BH,00H
MOV DH,16H
MOV DL,07H
INT 10H
MOV AH,02h
MOV DL,2Ah
INT 21h

MOV AH,02H
MOV BH,00H
MOV DH,17H
MOV DL,04H
INT 10H
MOV AH,02h
MOV DL,2Ah
INT 21h

MOV AH,02H
MOV BH,00H
MOV DH,18H
MOV DL,01H
INT 10H
MOV AH,02h
MOV DL,2Ah
INT 21h





int 20h
CODE ENDS
END START

这是我想要做的手动方式:)。我想增加或减少光标的行,循环内的列号,我尝试了这段代码

CODE SEGMENT
ASSUME CS:CODE
START:  

MOV CX,12
MOV DH,00H
MOV DL,00H

dongu:
MOV AH,02H
MOV BH,00H
MOV AH,02h
MOV DL,2Ah
inc dl
inc dh
INT 10H
loop dongu

INT 21h
int 20h
CODE ENDS
END START

但效果不好。

顺便说一句,对不起我的英语不好,这是我在 stackoverflow 上的第一篇文章。

【问题讨论】:

  • 'Isn't working well' 不是错误描述。要么您有正在处理的特定错误,要么存在重大的理解问题。请尽可能准确,否则我们无法/不想帮助您。
  • 确实不存在任何错误。我无法对角打印'*'字符。我分享了手动方式以获得更多可理解性。我会尽量注意规则。谢谢回复: )

标签: loops assembly x86-16 dosbox


【解决方案1】:

序言

MOV AH,06h ;INT 10,6
MOV AL,00h ;number of lines to scroll, previous lines are
;blanked, if 0 or AL > screen size, window is blanked
MOV CH,00h ;row of upper left corner of scroll window
MOV CL,00h ;column of upper left corner of scroll window
MOV DH,24h ;row of lower right corner of scroll window
MOV DL,79h ;column of lower right corner of scroll window
MOV BH,07h ;attribute to be used on blank line
INT 10h

上面的 sn -p 已经显示错误了。您对十进制和十六进制数字感到困惑。右下角的坐标是 (79,24)。您编写了更大的值 (79h,24h)=(119,36)。如果你幸运的话,BIOS 不会太介意,但你不能指望这种宽大处理。

MOV AH,02H
MOV BH,00H
MOV DH,18H
MOV DL,50H     <<<<< This is off-screen!
INT 10H
MOV AH,02h
MOV DL,2Ah
INT 21h

第一条对角线的最后一点在屏幕外。在接下来的解决方案中,我将更正此问题。

inc dl
inc dh

在您尝试编写一个在屏幕上产生对角线的循环时,您不会仅仅增加/减少光标的位置,因为

  • 屏幕不是方形的,这意味着DLDH 不会同步变化。
  • 水平尺寸远大于垂直尺寸,这意味着水平步长为 3 或 4,而垂直步长可以保持为 1。

解决方案

对于将产生与手动版本完全相同的输出的简单解决方案,您可以将要使用的坐标存储在数组中,然后循环遍历此数据。因为该行确实可以使用 1 递增,所以不需要存储垂直分量。由于第二条对角线与第一条对角线对称,因此无需为第二条对角线 (*) 存储单独的数据。
下一个代码将给出从 (3,1) 到 (79,24) 的第一个对角线

array   db 3,6,10,13,16,20, ... ,73,76,79,-1
    ...
    mov     cx, 1        ;Repetition count for BIOS function 09h
    mov     bx, 0007h    ;BH=Display page 0, BL=Attribute WhiteOnBlack
    mov     si, array
    mov     dh, 0        ;Row
again:
    inc     dh           ;Vertical step is fixed at 1
    mov     dl, [si]     ;Column
    mov     ah, 02h      ;SetCursor
    int     10h
    mov     ax, 092Ah    ;AH=BIOS function 09h, AL=Character "*"
    int     10h
    inc     si
    cmp     byte ptr [si], -1  ;Reached end of list marker?
    jne     again

请注意,我没有使用 DOS 函数 02h 来输出字符。由于此 DOS 输出功能会自动使光标前进,因此有时会干扰您的屏幕。我使用的 BIOS 输出功能不会使光标前进,因此非常适合您的程序。

仔细观察 (*)

array1  db 3,6,10,13,16,20, ... ,73,76,79,-1
array2  db 77,74,70,67,64,60, ... ,7,4,1,-1

如果您仔细查看第二条对角线的数字,您应该会发现与第一条对角线的数字相似。事实上,该列现在与屏幕的宽度互补:

77 = 80 -  3
74 = 80 -  6
70 = 80 - 10
...
 4 = 80 - 76
 1 = 80 - 79

现在我们可以利用它来编写第二条对角线的循环,只需对代码稍作改动:

array   db 3,6,10,13,16,20, ... ,73,76,79,-1
    ...
    mov     cx, 1        ;Repetition count for BIOS function 09h
    mov     bx, 0007h    ;BH=Display page 0, BL=Attribute WhiteOnBlack
    mov     si, array
    mov     dh, 0        ;Row
again:
    inc     dh           ;Vertical step is fixed at 1
    mov     dl, 80                              <<<<< Only changes
    sub     dl, [si]     ;Column                <<<<< Only changes
    mov     ah, 02h      ;SetCursor
    int     10h
    mov     ax, 092Ah    ;AH=BIOS function 09h, AL=Character "*"
    int     10h
    inc     si
    cmp     byte ptr [si], -1  ;Reached end of list marker?
    jne     again

我意识到这个答案中可能有很多新内容。请花时间理解我编写的每一行代码。不要仅仅复制它就满足自己。如有疑问,请不要犹豫发布有关此答案的 cmets!不客气。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多