I am writing a program that converts nonneg integers ranging from 0-4096 to a 3 digit hexadecimal number. Problem is that this program isn't even accepting my input. I am using SASM32 with custom macros. Instead, it overflows repeating the output messages and using 0 as our input. Also since the default for the return prompt is 'Y' it continues until a crash.
.486
include C:\Program Files (x86)\SASM\include\sasmacros.inc
.data
;Messages
inputmsg db 'Input decimal integer to convert:',0
outputmsg db 'in hexadecimal is:',0
reprompt_msg db 'Convert another integer? (Y/N):',0
reprompt_char db 'N'
;Variables
input_store dd 0
user_input dd 0
temp dd 0
remainder_store dd 0
quotient dd 0
remainder dd 0
temp_remainder dd 0
hexnumber dd 0 DUP(100)
output dd 1, 2, 3
;main loop control is positions and user_input
;record each hex position as a character or digit(either one will be 0 or digit)
positions dd 0
pos1 db '0'
pos2 db ' '
pos3 db ' '
.code
;take number and divide it by 16 and at the remainder of it to the output
;divide -> check remainder (if n > 9) -> add hex number loop -> divide loop
; store the quotient for the next iteration of dividing
; divide until our remainder or the result of our mod is == 0
;for reprompt just compare if N - N == 0 is true
;if input is less than 15 then just return it
start:
get_i user_input
move user_input, input_store ; store our input before it is lost
;might delete
;might delete
br divide
divide:
;divide by 16
move temp, user_input ; setting temp to the current input
idivi temp, 16
move quotient, temp ;quotient = temp
move temp, user_input ;temp = input
irem temp, 16 ; takes remainder of temp and saves it as temp
move remainder, temp ;remainder = temp
;set our input = quotient
move user_input, quotient ; storing our input for next loop as quotient
br store_result
store_result:
compare user_input, 0 ;if our user_input is 0 (which becomes the quotient of the previous calculation), then finish
bez return1 ; problem is that we would also hit this case if our input is 0
;check for 0
compare remainder, 10
bgez convert_to_upper_hex
;otherwise just store our remainder and loop again
;48 - remainder = character representation of remainder ASCII
iadd positions, 1 ; increment positions
iadd remainder, 48 ; create ascii value
br figure_what_to_store
;converts digits 10-15
convert_to_upper_hex:
iadd positions, 1 ;have to increment still in this loop
iadd remainder, 41 ;make it A-F using ASCII starting at 'A'
br figure_what_to_store
figure_what_to_store:
compare 1, positions
bez store_pos_one
compare 2, positions
bez store_pos_two
compare 3, positions
bez store_pos_three
store_pos_one:
move pos1, remainder ;move remainder into pos1
br divide
store_pos_two:
move pos2, remainder
br divide
store_pos_three:
move pos3, remainder
br return1
;end loop here
return1:
put_i input_store
put_str outputmsg
;update displaying integer
compare positions, 1
bez return_single
compare positions, 2
bez return_double
;if we aren't displaying 1 or 2 digits, then we are displaying 3
put_ch pos3
put_ch pos2
put_ch pos1
;check if more positions, if so bnz return
br reprompt
return_single:
put_ch pos1
br reprompt
return_double:
put_ch pos2
put_ch pos1
br reprompt
reprompt:
put_str reprompt_msg
get_ch reprompt_char
compare reprompt_char, 'Y' ;if N was entered
bez reprompt_flag
reprompt_flag:
;also clear output
br start
exit
end start
CodePudding user response:
move user_input, input_store ; store our input before it is lost ;divide by 16 move temp, user_input ; setting temp to the current input
There's something very wrong here about the direction of these operations!
In move user_input, input_store
, I'd expect source -> destination
, but in
move temp, user_input
it's rather destination <- source
.
It can't be both at the same time...
Assuming destination <- source
this is what happens:
- Because input_store holds 0, the line
move user_input, input_store
destroys the input and makes it zero. - The calculations for both quotient and remainder will yield zero.
- After loading the user_input from quotient it will be zero (again).
- Finally
compare user_input, 0
bez return1
will always jump to return1.
compare reprompt_char, 'Y' ;if N was entered bez reprompt_flag reprompt_flag: br start
Code like the above constitutes an endless loop. If the answer was 'Y', you branch to the instruction that goes to start, and if the answer is not 'Y' (which is not the same as having entered 'N') you fall through in the instruction that goes to start. Either way you repeat the program.
Try the following. This way the user answering 'Y' will rerun the program, while any other answer will fall through in the exit.
reprompt:
put_str reprompt_msg
get_ch reprompt_char
compare reprompt_char, 'Y'
bez start
exit
end start