How do I print multiple variables in assembly x86?

I’m trying to print "varc1", "varc2" and "varsm" on the screen but after printing the first variable my program gets into a weird loop. I copied the code related to the printing from this question and I added new lines (whitespaces) so I can differenciate between variables.

;varc1 -> 1's complement of the initial 16 bits number
;varc2 -> 2's complement of the initial 16 bits number
;varsm -> Sign change of the initial 16 bits number. The representation system used is sign-magnitude.  

.model small
.stack 100h
.data
    Texto DB "Please enter a 16 bits number: ",13,10,'$'
    MaximoMas1 DB 17
    CaracteresLeidos DB 0
    Cadena DB 17 DUP (0) ;Setting all the bits to 0 ("seventeen duplicates of zero") 
    linefeed DB 13, 10, "$"
    
    varc1 DW 0000h
    varc2 DW 0000h
    varsm DW 0000h
.code
Inicio:
    mov ax, @data
    mov ds, ax
    
    mov ah, 9           ;We set ah to 9 so the int 21h function displays the text on the screen
    lea dx, Texto       ;Load effective address
    int 21h
    
    mov ah, 0Ah         ;We set ah to 0Ah so the int 21h function reads a string character from keyboard and store it on memory
    lea dx, MaximoMas1
    int 21h
    
    mov cx, 16
    xor si, si          ;Setting si to 0.
    
    bucle:
    mov al, Cadena[si]
    shr ax,1            ;Shifts to the right side one by one by inserting the same number (bits that are being shifted) of zeroes from the left end.
    rcl bx,1            ;Rotate Carry Left. Rotates the mentioned bits in the register to the left side one by one such that leftmost bit that is being rotated it is stored in the Carry Flag (CF), and the bit in the CF moved as the LSB in the register.  
    inc si
    loop bucle
    
    not bx              ;For getting the C1 
    mov varc1, bx
    not bx              ;Reset to normal after doing a "not"
    
    neg bx              ;Negates a value by finding 2's complement of its single operand
    mov varc2, bx
    
    neg bx
    xor bx, 8000h       ;We change the leftmost bit so its in sign-magnitude
    mov varsm, bx
    
    mov ah, 09
    mov dx, offset linefeed
    int 21h 
    
    mov ax,varc1
    print_hex:
    mov cx,4        ; print 4 hex digits (= 16 bits)
    .print_digit: 
        rol ax,4    ; move the currently left-most digit into the least significant 4 bits
        mov dl,al
        and dl,0xF  ; isolate the hex digit we want to print
        add dl,'0'  ; and convert it into a character..
        cmp dl,'9'  ; ...
        jbe .ok     ; ...
        add dl,7    ; ... (for 'A'..'F')
    .ok:            ; ...
        push ax     ; save AX on the stack temporarily
        mov ah,2    ; INT 21H / AH=2: write character to stdout
        int 21h
        pop ax      ; restore AX
        loop .print_digit
        ret
      
        
    mov ah, 09
    mov dx, offset linefeed
    int 21h
                 
    mov ax,varc2
    jmp print_hex 
              
    mov ax,varsm
    jmp print_hex
     
    mov ah, 4Ch
    int 21h
END Inicio

How can I solve this issue? Is it because of the final "ret"? Should I use a different JMP instruction for doing the "print function" with another variable?

>Solution :

print_hex is supposed to called. Otherwise, the ret will fail to return back to where you came from.
That is, the code should look something like:

mov ax, varc1
call print_hex

mov ah, 09
mov dx, offset linefeed
int 21h

mov ax, varc2
call print_hex

mov ah,4ch
int 21h

print_hex:
mov cx,4        ; print 4 hex digits (= 16 bits)
.print_digit: 
    rol ax,4    ; move the currently left-most digit into the least significant 4 bits
    mov dl,al
    and dl,0xF  ; isolate the hex digit we want to print
    add dl,'0'  ; and convert it into a character..
    cmp dl,'9'  ; ...
    jbe .ok     ; ...
    add dl,7    ; ... (for 'A'..'F')
.ok:            ; ...
    push ax     ; save AX on the stack temporarily
    mov ah,2    ; INT 21H / AH=2: write character to stdout
    int 21h
    pop ax      ; restore AX
    loop .print_digit
    ret 

Leave a Reply