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?
CodePudding user response:
print_hex
is supposed to call
ed. 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