This is how it handles input:
- if negative, terminate program
- if 0-2, display input without calculating
- if greater than or equal to 3, calculate and display result
I have also used some macros from an included file:
nwln
: outputs a newlinePutStr
: displays a labelGetLInt
: receives a 32-bit integerPutLInt
: displays a 32-bit integer
My questions:
- Is my input validation reducing readability, or is that not important as long as the program proceeds with only the correct input?
- Should I need to check for non-numerical values, or does it not really matter?
- Since the result register (
EAX
) is 32-bit, should I take into account a possible result that may not fit in 32 bits? If I get a larger result, it won't display properly, and the user may be unaware. - Is doing a bunch of adds still faster than using
mul
? I'm also avoidingmul
because I still have trouble getting all the bits in the right place. - Should any of these procedures be organized differently? I'm still not sure how important this is in assembly when most procedures have jumps or branches. In this program, it makes sense to have
check_input
afterget_input
and with no jump in between them.
Other than that, I'd like a review on anything you may find.
%include "macros.s"
.DATA
input_lbl: DB "Number: ", 0
bad_input_lbl: DB "Number must be positive!", 0
result_lbl: DB "Total: ", 0
input: DD 0
result: DD 0
.CODE
.STARTUP
; EAX - input
; EBX - input (for counter)
get_input:
PutStr input_lbl
GetLInt [input]
mov EAX, [input]
mov EBX, [input]
; EBX - input
check_input:
; terminate if input is negative
cmp EBX, 0
jl report_bad_input
; no need to calculate if below 3
cmp EBX, 3
jge calc_factorial
; input is 0, 1, or 2
jmp display_result
report_bad_input:
PutStr bad_input_lbl
.EXIT
; EAX - result
display_result:
nwln
mov [result], EAX
PutStr result_lbl
PutLInt [result]
.EXIT
; EAX - current value
; EBX - counter
; ECX - current total (for multiplication)
; EDX - counter (for multiplication)
calc_factorial:
; no need to multiply by 1
dec EBX
cmp EBX, 1
je display_result
; perform addition instead of multiplication
mov ECX, EAX
mov EDX, EBX
jmp mult_with_addition
jmp calc_factorial
; EAX - current total
; ECX - current total (for multiplication)
; EDX - counter (for multiplication)
mult_with_addition:
; determine if addition should stop
dec EDX
cmp EDX, 0
je calc_factorial
add EAX, ECX
jmp mult_with_addition
Sample tests:
Input: 3
Output: 6Input: 2
Output: 2Input: 1
Output: 1Input: 0
Output: 0Input: -1
Output: "Number must be positive!"