Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- .MODEL SMALL
- .STACK 100h
- .DATA ; Data segment for variables and messages
- ; Variables
- input_integer DB '$$$$$$$$$$' ; Buffer to store input string
- num_one DW ? ; First number
- num_two DW ? ; Second number
- sum DW ? ; Sum of the numbers
- product DW ? ; Product of the numbers
- string_sum DW '$$' ; String to hold formatted sum
- string_product DW '$$' ; String to hold formatted product
- len DB 0
- ; Messages
- input_prompt DB 13, 10, 'Enter a number (0 - 99): $'
- invalid_input_prompt DB 13, 10, 13, 10, 'Invalid input!!!', 13, 10, '$'
- integer_out_of_range_prompt DB 13, 10, 13, 10, 'Input out of range! Must be (0 - 9).', 13, 10, '$'
- echo_sum DB 13, 10, 'The Sum: $'
- echo_product DB 13, 10, 'The Product: $'
- .CODE ; Denotes the start of the code segment
- MAIN PROC ; Defines the main procedure (program entry point)
- ; Set up data segment
- MOV AX, @data ; Move address of data segment to AX register
- MOV DS, AX ; Set the data segment register (DS) to the address in AX
- ; Get the first number
- get_num_one:
- CALL SCANF_INTEGER ; Call procedure to prompt user and read integer input
- CMP CX, 3 ; Checks if the length of the input is greater than 3, if so it means it is 100 or greater
- JL set_num_one ; Process continues if it is below length of 2
- ; Is called if input is greater than 99
- CALL INTEGER_OUT_OF_RANGE
- JMP get_num_one
- set_num_one:
- PUSH OFFSET input_integer ; Push address of input buffer onto stack (for PARSE_INTEGER)
- CALL PARSE_INTEGER ; Call procedure to convert string input to integer
- MOV num_one, BX ; Move parsed integer from BX to num_one variable
- ; Get the second number (similar steps as above)
- get_num_two:
- CALL SCANF_INTEGER
- CMP CX, 3
- JL set_num_two
- CALL INTEGER_OUT_OF_RANGE
- JMP get_num_two
- set_num_two:
- PUSH OFFSET input_integer
- CALL PARSE_INTEGER
- MOV num_two, BX
- ; Perform addition and display sum
- CALL ADDITION ; Call procedure to add num_one and num_two
- CALL PARSE_SUM ; Call procedure to convert sum to string representation
- CALL DISPLAY_SUM ; Call procedure to display the sum on the console
- ; Perform multiplication and display product
- CALL MULTIPLICATION ; Call procedure to multiply num_one and num_two
- CALL PARSE_PRODUCT ; Call procedure to convert product to string representation
- CALL DISPLAY_PRODUCT ; Call procedure to display the product on the console
- ; Terminate the program
- MOV AH, 4Ch ; Set interrupt code for program termination (4Ch)
- INT 21h ; Trigger interrupt to end program
- MAIN ENDP ; End of the main procedureSCANF_INTEGER PROC
- SCANF_INTEGER PROC
- ; Preserve registers to avoid side effects
- PUSH AX ; Save AX on the stack
- PUSH BX ; Save BX on the stack
- PUSH SI ; Save SI on the stack
- next_integer:
- ; Initialize variables for input reading
- XOR SI, SI ; Set SI (character counter) to zero
- LEA BX, input_integer ; Load address of input_integer buffer into BX
- ; Print prompt for user input
- LEA DX, input_prompt ; Load address of prompt message
- MOV AH, 09h ; DOS function to display string
- INT 21h ; Call DOS interrupt to display prompt
- read_next_char:
- ; Read a character from standard input
- MOV AH, 01h ; DOS function to read character
- INT 21h ; Call DOS interrupt to read input
- ; Validate the input character
- validate_input:
- CMP AL, 13 ; Check if Enter key was pressed (13 = carriage return)
- JE done_reading ; If Enter pressed, jump to done_reading
- ; Check if character is a valid digit (0-9)
- CMP AL, '0' ; Compare with '0'
- JL invalid_input ; If less than '0', jump to invalid_input
- CMP AL, '9' ; Compare with '9'
- JG invalid_input ; If greater than '9', jump to invalid_input
- ; Store valid character in the input_integer buffer
- MOV [BX+SI], AL ; Store character at BX+SI offset
- INC SI ; Increment counter
- JMP read_next_char ; Continue reading next character
- invalid_input:
- ; Print invalid input message
- LEA DX, invalid_input_prompt ; Load address of invalid input message
- MOV AH, 09h ; DOS function to display string
- INT 21h ; Call DOS interrupt to display message
- JMP next_integer ; Restart input process
- done_reading:
- ; Terminate the string with a null terminator
- MOV AL, '$' ; Load dollar sign (string terminator)
- MOV [BX+SI], AL ; Store terminator at the end of input
- MOV CX, SI ; Save the character count in CX
- ; Restore original register values
- POP SI ; Restore SI from the stack
- POP BX ; Restore BX from the stack
- POP AX ; Restore AX from the stack
- RET ; Return from the procedure
- SCANF_INTEGER ENDP
- PARSE_INTEGER PROC
- ; Set up variables
- MOV SI, OFFSET input_integer ; Load address of input string into SI
- MOV BX, 0 ; Initialize BX to hold the parsed integer (0)
- iterate:
- ; Check for end of string
- XOR AX, AX
- MOV AX, [SI] ; Load character from input string at SI
- CMP AL, '$' ; Compare with dollar sign terminator
- JE exit ; Jump to exit if it's the terminator
- ; Convert ASCII digit to numeric value (0-9)
- SUB AX, 48 ; Subtract '0' from ASCII code to get digit value
- CMP CX, 1 ; Check if this is the first digit
- JE add ; If first digit, jump to add (no multiplication)
- MOV DX, 10 ; Otherwise, set multiplier to 10
- MUL DX ; Multiply current value by 10 (for multiple digits)
- add:
- ; Add the digit value to the parsed integer
- ADD BX, AX ; Add current digit value to BX
- ; Update loop variables
- INC SI ; Increment SI to point to next character
- DEC CX ; Decrement counter for number of digits
- ; Continue iterating until all characters are processed
- CMP CX, 0 ; Check if counter reaches zero
- JNE iterate ; Jump back to iterate if not done
- exit:
- ; Procedure finished
- RET ; Return from the procedure
- PARSE_INTEGER ENDP
- ADDITION PROC
- ; Get operands from variables
- MOV AX, num_one ; Load the value of num_one into AX
- ; Add the operands
- MOV BX, num_two ; Load the value of num_two into BX
- ADD AX, BX ; Add the values in AX and BX, storing the result in AX
- ; Store the result in the sum variable
- MOV sum, AX ; Move the sum from AX to the sum variable
- ; Return from the procedure
- RET ; Return control to the calling procedure
- ADDITION ENDP
- MULTIPLICATION PROC
- ; Get operands from variables
- MOV AX, num_one ; Load the value of num_one into AX
- XOR AH, AH ; Clear the upper byte of AX (important for unsigned multiplication)
- ; Get operand from variable and clear upper byte
- MOV BX, num_two ; Load the value of num_two into BX
- XOR BH, BH ; Clear the upper byte of BX (important for unsigned multiplication)
- ; Perform unsigned multiplication
- MUL BX ; Multiply the values in AX and BX, storing the result in AX and DX
- ; Store the result (lower 16 bits) in the product variable
- MOV product, AX ; Move the lower 16 bits of the product (in AX) to the product variable
- ; Return from the procedure
- RET ; Return control to the calling procedure
- MULTIPLICATION ENDP
- PARSE_SUM PROC
- ; Set up variables
- MOV AX, sum ; Load the value of the sum from the sum variable into AX
- XOR AH, AH ; Clear the upper byte of AX (important for converting to ASCII)
- XOR CX, CX ; Initialize CX to zero (used as a counter)
- add_next_div:
- ; Prepare for division (remainder in DX, quotient in AX)
- XOR DX, DX ; Clear the DX register (important for division)
- MOV BX, 10 ; Set divisor to 10 (for extracting digits)
- DIV BX ; Perform unsigned division of AX by 10
- ; - Quotient (result of division) is stored in AX
- ; - Remainder is stored in DX
- ; Convert remainder digit to ASCII
- ADD DX, '0' ; Add '0' to the remainder (DX) to get the corresponding ASCII digit character
- ; Store the digit character and update loop variables
- PUSH DX ; Push the digit character onto the stack (for string building)
- INC CX ; Increment the counter (CX) for the number of digits
- CMP AX, 0 ; Check if the quotient (AX) is zero (indicating all digits processed)
- JE add_pop_queue ; If zero, jump to add_pop_queue (to build the string)
- JMP add_next_div ; Otherwise, continue dividing by 10 (extract next digit)
- add_pop_queue:
- ; Set up for building the string in string_sum
- LEA BX, string_sum ; Load the address of string_sum into BX (destination for the string)
- XOR SI, SI ; Initialize SI as a string counter (offset within string_sum)
- add_pop_next:
- ; Pop digit characters from the stack and build the string
- POP DX ; Pop a digit character from the stack
- MOV [BX+SI], DL ; Move the digit character (lower byte of DX) to the string_sum at current offset
- INC SI ; Increment the string counter (SI)
- LOOP add_pop_next ; Loop back to pop_next until all digits are processed from the stack
- ; Add string terminator ('$')
- MOV DL, '$' ; Load the dollar sign character into DL
- MOV [BX+SI], DL ; Move the terminator character to the end of the string_sum
- ; Return the address of the converted string
- MOV DX, BX ; Move the base address of string_sum into DX to return
- RET ; Return from the procedure
- PARSE_SUM ENDP
- PARSE_PRODUCT PROC
- ; Set up variables
- MOV AX, product ; Load the value of the product from the product variable into AX
- XOR CX, CX ; Initialize CX to zero (used as a counter)
- mult_next_div:
- ; Prepare for division (remainder in DX, quotient in AX)
- XOR DX, DX ; Clear the DX register (important for division)
- MOV BX, 10 ; Set divisor to 10 (for extracting digits)
- DIV BX ; Perform unsigned division of AX by 10
- ; - Quotient (result of division) is stored in AX
- ; - Remainder is stored in DX
- ; Convert remainder digit to ASCII
- ADD DX, '0' ; Add '0' to the remainder (DX) to get the corresponding ASCII digit character
- ; Store the digit character and update loop variables
- PUSH DX ; Push the digit character onto the stack (for string building)
- INC CX ; Increment the counter (CX) for the number of digits
- CMP AX, 0 ; Check if the quotient (AX) is zero (indicating all digits processed)
- JE mult_pop_queue ; If zero, jump to mult_pop_queue (to build the string)
- JMP mult_next_div ; Otherwise, continue dividing by 10 (extract next digit)
- mult_pop_queue:
- ; Set up for building the string in string_product
- LEA BX, string_product ; Load the address of string_product into BX (destination for the string)
- XOR SI, SI ; Initialize SI as a string counter (offset within string_product)
- mult_pop_next:
- ; Pop digit characters from the stack and build the string
- POP DX ; Pop a digit character from the stack
- MOV [BX+SI], DL ; Move the digit character (lower byte of DX) to the string_product at current offset
- INC SI ; Increment the string counter (SI)
- LOOP mult_pop_next ; Loop back to pop_next until all digits are processed from the stack
- ; Add string terminator ('$')
- MOV DL, '$' ; Load the dollar sign character into DL
- MOV [BX+SI], DL ; Move the terminator character to the end of the string_product
- ; Return the address of the converted string
- MOV DX, BX ; Move the base address of string_product into DX to return
- RET ; Return from the procedure
- PARSE_PRODUCT ENDP
- DISPLAY_SUM PROC
- ; Display message "The sum is: "
- LEA DX, echo_sum ; Load the address of the message string "The sum is: " into DX
- MOV AH, 09h ; Set interrupt code for displaying a string (DOS function)
- INT 21h ; Trigger interrupt to display the message
- ; Display the actual sum value
- LEA DX, string_sum ; Load the address of the converted sum string (from PARSE_SUM) into DX
- MOV AH, 09h ; Set interrupt code for displaying a string (DOS function)
- INT 21h ; Trigger interrupt to display the sum value
- RET ; Return from the procedure
- DISPLAY_SUM ENDP
- DISPLAY_PRODUCT PROC
- ; Display message "The product is: "
- LEA DX, echo_product ; Load the address of the message string "The product is: " into DX
- MOV AH, 09h ; Set interrupt code for displaying a string (DOS function)
- INT 21h ; Trigger interrupt to display the message
- ; Display the actual product value
- LEA DX, string_product ; Load the address of the converted product string (from PARSE_PRODUCT) into DX
- MOV AH, 09h ; Set interrupt code for displaying a string (DOS function)
- INT 21h ; Trigger interrupt to display the product value
- RET ; Return from the procedure
- DISPLAY_PRODUCT ENDP
- INTEGER_OUT_OF_RANGE PROC
- ; Display message "Input out of range. Must be (0 - 9)."
- LEA DX, integer_out_of_range_prompt
- MOV AH, 09h ; Set interrupt code for displaying a string (DOS function)
- INT 21h ; Trigger interrupt to display the product value
- RET ; Return from the procedure
- INTEGER_OUT_OF_RANGE ENDP
- END
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement