如果只输入相同的代码3次

时间:2017-11-11 03:46:40

标签: assembly x86 dos x86-16

如果只使用新的行代码打印新行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 个答案:

答案 0 :(得分:2)

您所要做的就是将您已编写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实现,即使API另有规定,也会破坏AX注册。

作为一个例子,为了表明你可以在不调用子程序的情况下编写它,这里是一个使用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

答案 1 :(得分:1)

首先创建一个子程序/函数,您可以从主代码中调用它,例如在您的主代码放入之后:

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通过它的代码,在调试器中尝试它是如何工作的(以及返回的地址是什么) stack do),那么整个新的子程序代码将是:

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新线路输出。

不那么令人困惑和棘手的变种&#34;三次&#34;子程序当然是:

PRINT_NEW_LINE_THRICE:
    CALL PRINT_NEW_LINE
    CALL PRINT_NEW_LINE
    CALL PRINT_NEW_LINE
    RET