Rubel Biswas
Rubel Biswas

Reputation: 1444

How can i print new line 3 times by using new line code only once in-spite of typing same code 3 times

How can i print new line 3 times by using new line code only once in-spite of typing same code 3 times

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  

Upvotes: 0

Views: 992

Answers (2)

Sep Roland
Sep Roland

Reputation: 39621

All you have to do is put the block of newline code, that you have written 3 times, in a subroutine that you can call instead.

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

Now the part of your program that displays the results becomes:

    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. Don't feel compelled to remove as much mov ah, 02h as you can. Leaving those in makes for a well documented program and over the years I have seen BIOS/DOS implementations that do clobber the AX register even when the API stated otherwise.


As an example, and to show that you can write it without calling a subroutine, here's a version that uses a loop as was hinted in 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

Upvotes: 2

Ped7g
Ped7g

Reputation: 16606

create first a subroutine/function which you can call from main code, for example after your main code put this:

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

And now I will use some ugly trickery to create also 2x and 3x variants not just by simply calling the subroutine above, but letting the CPU to fall through its code, try it in debugger how it works (and what return addresses in stack do), then the whole new subroutines code will be:

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

Now in your main code simply do:

    CALL PRINT_NEW_LINE_THRICE

to get 3x new line outputted.


The less confusing and tricky variant of "thrice" subroutine would be of course:

PRINT_NEW_LINE_THRICE:
    CALL PRINT_NEW_LINE
    CALL PRINT_NEW_LINE
    CALL PRINT_NEW_LINE
    RET

Upvotes: 1

Related Questions