Hey I need to write an assembly language program that gets two strings from user, then determines which one is longer and how much and prints the results on the screen.
Please look at the code below:
data segment
prpt1 db 'Enter the first string: $'
prpt2 db 0Dh, 0Ah,'Enter the second string: $'
msg1 db 0Dh, 0Ah, 'The first string is longer by $'
msg2 db 0Dh, 0Ah, 'The second string is longer by $'
msg3 db 0Dh, 0Ah, 'The strings are of equal length$'
in_str1 db 255, ?, 255 dup('$')
in_str2 db 255, ?, 255 dup('$')
data ends
code segment
assume cs: code, ds: data
start: mov ax, data
mov ds, ax
; displaying the prompt to user that he should enter the first string
lea dx, prpt1
mov ah, 09h
int 21h
; getting the first string from user
lea dx, in_str1
mov ah, 0Ah
int 21h
; displaying the prompt to user that he should enter the second string
lea dx, prpt2
mov ah, 09h
int 21h
; getting the second string from user
lea dx, in_str2
mov ah, 0Ah
int 21h
; storing the first string length in al, the second string length in ah
mov al, in_str1+1
mov ah, in_str2+1
; calculating the difference
sub al, ah
; if we get zero, it means the lengths of the strings are equal, so we inform the user about it and quit the program
jnz neq
mov ah, 09h
lea dx, msg3
int 21h
jmp quit
; if we haven't gotten zero that time, we check if the sign flag has been modified then
neq: js le
; if the sign flag hasn't been changed to 1, then it means that al is positive
xor ah, ah ; flushing ah so that we won't be having problems interpreting what is stored in ax
push ax ; we want to save the difference between the two lengths (which is in al now), so we push ax into the stack
; printing the message saying that string in_str1 is longer than string in_str2
mov ah, 09h
lea dx, msg1
int 21h
jmp print
; if the sign flag has not been changed to 1, then it means that al is negative, we need to change its sign
le: xor ah, ah
neg al
push ax
; printing the message saying that string in_str2 is longer than string in_str1
mov ah, 09h
lea dx, msg2
int 21h
; printing what is in al (the difference between the two lengths), digit by digit
print: xor cx, cx ; we will be using cx to count how many digits are to be printed
mov bx, 10 ; we will be repeatedly dividing ax by 10 and printing the remainder onto the screen
pop ax ; retrieving the difference that we put in the stack previously
loop1: xor dx, dx ; we flush dx so as not to get overflow when dividing
div bx
push dx ; saving the remainder, a digit (reading from right to left) of the number
inc cx
test ax, ax ; we check if the result of dividing is zero. If it is so, then it means we have gotten all the digits of the number
jnz loop1
mov ah, 02h
loop2: pop dx ; retrieving a digit of the difference
add dl, '0' ; getting the code of the coresponding ASCII character in dl
int 21h ; printing the said character
dec cx
jnz loop2
quit: mov ax, 4C00h
int 21h
code ends
end start
and tell me something.
(1) Why do we sometimes get overflow when dividing if the dx register has not been not flushed before the division?
(2) Why do we have to XOR dx, dx before every time we perform division? I noticed that if we don't do that, we may get wrong result it ax and dx. Say, we devide 52h (82) by 0Ah (10), getting 8 in ax and 2 in dx. If we then divide 8 by 10, we get some unexpected 3334h in ax, 0 in dx. How would you explain this?
(3) Can you think of a more reasonable way of handling certain things in the program? Maybe some pieces of it could be simplified or improved in some way.
PS I run it via emu8086