尽管输入相同的代码 3 次,但如何仅使用一次换行代码打印换行 3 次
How can i print new line 3 times by using new line code only once in-spite of typing same code 3 times
尽管输入相同的代码 3 次,但我如何仅使用一次换行代码打印新行 3 次
include emu8086.inc
ORG 100h
PRINT 'ENTER THREE INITIALS: '
MOV AH,1
INT 21H
MOV BL,AL
INT 21H
MOV CL,AL
INT 21H
MOV BH,AL
MOV AH,2
MOV DL,10
INT 21H ;NEW LINE
MOV DL,13
INT 21H
MOV AH,2
MOV DL,BL
INT 21h
MOV AH,2
MOV DL,10
INT 21H ;NEW LINE
MOV DL,13
INT 21H
MOV DL,CL
INT 21h
MOV AH,2
MOV DL,10
INT 21H ;NEW LINE
MOV DL,13
INT 21H
MOV DL,BH
INT 21h
RET
END
首先创建一个 subroutine/function,您可以从主代码中调用它,例如在您的主代码放置以下内容之后:
PRINT_NEW_LINE:
MOV AH,2
MOV DL,10
INT 21H ;NEW LINE (that's really amazing comment... not)
MOV DL,13 ; and now I realized you do 10,13 output
INT 21H ; but correct DOS <EOL> is 13,10
RET ; time to fix all that in next version below...
现在我将使用一些丑陋的技巧来创建 2x 和 3x 变体,不仅仅是简单地调用上面的子例程,而是让 CPU 遍历它的代码,在调试器中尝试它是如何工作的(以及堆栈中 return 地址的作用),那么整个新的子程序代码将是:
PRINT_NEW_LINE_THRICE:
CALL PRINT_NEW_LINE ; do 1x EOL, and then fall into "twice" code
PRINT_NEW_LINE_TWICE:
CALL PRINT_NEW_LINE ; do 1x EOL, and then fall into it again
PRINT_NEW_LINE:
PUSH AX
PUSH DX ; store original ax, dx values
MOV AH,2
MOV DL,13
INT 21H ; output NL (new line)
MOV DL,10
INT 21H ; output CR (carriage return)
POP DX ; restore original ax, dx value
POP AX
RET
现在在您的主要代码中只需执行以下操作:
CALL PRINT_NEW_LINE_THRICE
输出 3x 新行。
"thrice" 子程序的不那么混乱和棘手的变体当然是:
PRINT_NEW_LINE_THRICE:
CALL PRINT_NEW_LINE
CALL PRINT_NEW_LINE
CALL PRINT_NEW_LINE
RET
您所要做的就是将您已编写 3 次的 换行代码块 放入您可以 call
代替的子例程中。
PrintCRLF:
push ax
push dx
mov dl, 13 ;Carriage return
mov ah, 02h ;DOS.DisplayCharacter
int 21h
mov dl, 10 ;Linefeed
mov ah, 02h ;DOS.DisplayCharacter
int 21h
pop dx
pop ax
ret
现在显示结果的程序部分变为:
call PrintCRLF
mov dl, bl ;1st initial
mov ah, 02h ;DOS.DisplayCharacter
int 21h
call PrintCRLF
mov dl, cl ;2nd initial
mov ah, 02h ;DOS.DisplayCharacter
int 21h
call PrintCRLF
mov dl, bh ;3rd initial
mov ah, 02h ;DOS.DisplayCharacter
int 21h
ps。不要觉得有必要尽可能多地删除 mov ah, 02h
。将这些保留在一个有据可查的程序中,多年来我看到 BIOS/DOS 实现会破坏 AX
寄存器,即使 API 另有说明也是如此。
作为示例,为了表明您可以在不调用子例程的情况下编写它,这里有一个使用循环的版本,如 :
中所暗示的
push ax ;3rd initial in AL
push cx ;2nd initial in CL
push bx ;1st initial in BL
mov cx, 3
Next:
mov dl, 13 ;Carriage return
mov ah, 02h ;DOS.DisplayCharacter
int 21h
mov dl, 10 ;Linefeed
mov ah, 02h ;DOS.DisplayCharacter
int 21h
pop dx ;Pops 1st, 2nd, and 3rd initial to DL
mov ah, 02h ;DOS.DisplayCharacter
int 21h
dec cx
jnz Again
尽管输入相同的代码 3 次,但我如何仅使用一次换行代码打印新行 3 次
include emu8086.inc
ORG 100h
PRINT 'ENTER THREE INITIALS: '
MOV AH,1
INT 21H
MOV BL,AL
INT 21H
MOV CL,AL
INT 21H
MOV BH,AL
MOV AH,2
MOV DL,10
INT 21H ;NEW LINE
MOV DL,13
INT 21H
MOV AH,2
MOV DL,BL
INT 21h
MOV AH,2
MOV DL,10
INT 21H ;NEW LINE
MOV DL,13
INT 21H
MOV DL,CL
INT 21h
MOV AH,2
MOV DL,10
INT 21H ;NEW LINE
MOV DL,13
INT 21H
MOV DL,BH
INT 21h
RET
END
首先创建一个 subroutine/function,您可以从主代码中调用它,例如在您的主代码放置以下内容之后:
PRINT_NEW_LINE:
MOV AH,2
MOV DL,10
INT 21H ;NEW LINE (that's really amazing comment... not)
MOV DL,13 ; and now I realized you do 10,13 output
INT 21H ; but correct DOS <EOL> is 13,10
RET ; time to fix all that in next version below...
现在我将使用一些丑陋的技巧来创建 2x 和 3x 变体,不仅仅是简单地调用上面的子例程,而是让 CPU 遍历它的代码,在调试器中尝试它是如何工作的(以及堆栈中 return 地址的作用),那么整个新的子程序代码将是:
PRINT_NEW_LINE_THRICE:
CALL PRINT_NEW_LINE ; do 1x EOL, and then fall into "twice" code
PRINT_NEW_LINE_TWICE:
CALL PRINT_NEW_LINE ; do 1x EOL, and then fall into it again
PRINT_NEW_LINE:
PUSH AX
PUSH DX ; store original ax, dx values
MOV AH,2
MOV DL,13
INT 21H ; output NL (new line)
MOV DL,10
INT 21H ; output CR (carriage return)
POP DX ; restore original ax, dx value
POP AX
RET
现在在您的主要代码中只需执行以下操作:
CALL PRINT_NEW_LINE_THRICE
输出 3x 新行。
"thrice" 子程序的不那么混乱和棘手的变体当然是:
PRINT_NEW_LINE_THRICE:
CALL PRINT_NEW_LINE
CALL PRINT_NEW_LINE
CALL PRINT_NEW_LINE
RET
您所要做的就是将您已编写 3 次的 换行代码块 放入您可以 call
代替的子例程中。
PrintCRLF:
push ax
push dx
mov dl, 13 ;Carriage return
mov ah, 02h ;DOS.DisplayCharacter
int 21h
mov dl, 10 ;Linefeed
mov ah, 02h ;DOS.DisplayCharacter
int 21h
pop dx
pop ax
ret
现在显示结果的程序部分变为:
call PrintCRLF
mov dl, bl ;1st initial
mov ah, 02h ;DOS.DisplayCharacter
int 21h
call PrintCRLF
mov dl, cl ;2nd initial
mov ah, 02h ;DOS.DisplayCharacter
int 21h
call PrintCRLF
mov dl, bh ;3rd initial
mov ah, 02h ;DOS.DisplayCharacter
int 21h
ps。不要觉得有必要尽可能多地删除 mov ah, 02h
。将这些保留在一个有据可查的程序中,多年来我看到 BIOS/DOS 实现会破坏 AX
寄存器,即使 API 另有说明也是如此。
作为示例,为了表明您可以在不调用子例程的情况下编写它,这里有一个使用循环的版本,如
push ax ;3rd initial in AL
push cx ;2nd initial in CL
push bx ;1st initial in BL
mov cx, 3
Next:
mov dl, 13 ;Carriage return
mov ah, 02h ;DOS.DisplayCharacter
int 21h
mov dl, 10 ;Linefeed
mov ah, 02h ;DOS.DisplayCharacter
int 21h
pop dx ;Pops 1st, 2nd, and 3rd initial to DL
mov ah, 02h ;DOS.DisplayCharacter
int 21h
dec cx
jnz Again