2017-11-11 229 views
0

如何在只使用新行代码的情况下打印新行3次尽管输入了相同的代码3次如何在只使用一次新行代码的情况下使用新行代码打印新行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 
+2

我觉得你刚才问如何重复3次而不重复代码。把你的代码放在一个循环中。或者在一个你称之为3次的函数中。 –

回答

0

首先创建一个子程序/功能,你可以从主代码主代码把这个调用后,例如:

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... 

现在我会用一些丑陋的权谋也创造2倍和3x变体,不仅仅是通过调用上面的子程序,而是让CPU通过它的代码来尝试我吨调试器它是如何工作的(什么返回地址在堆栈做),那么整个新的子程序代码将是:

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 

获得3倍输出新行。


“三次”子程序的减少混乱和棘手的变异是当然的:

PRINT_NEW_LINE_THRICE: 
    CALL PRINT_NEW_LINE 
    CALL PRINT_NEW_LINE 
    CALL PRINT_NEW_LINE 
    RET 
1

所有您需要做的就是把的换行代码块,你已经写了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声明的时候也是如此。


作为一个例子,说明你可以写它不调用一个子程序,这里是一个使用作为this comment在暗示一个循环的一个版本:

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