2017-11-11 239 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