Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- .model small
- .stack 100h
- .data
- title_msg db "Piecewise Function Calculator", 13, 10, '$'
- equation_msg1 db "Function Z is defined as:", 13, 10, '$'
- equation_msg2 db " x-1 if x < 10", 13, 10, '$'
- equation_msg3 db "Z= (3x^2+4)/(x-2) if x = 10", 13, 10, '$'
- equation_msg4 db " (7x^2-56)/(2x-5) if x > 10", 13, 10, '$'
- instruction_msg db 13, 10, "Press ESC to exit, any other key to continue...", 13, 10, '$'
- prompt_msg db 13, 10, 'Enter value of x: $'
- error_msg db 13, 10, 'Invalid input! Please enter a valid number.$'
- overflow_msg db 13, 10, 'Overflow occurred during calculation!$'
- div_zero_msg db 13, 10, 'Error: Division by zero!$'
- result_msg db 13, 10, 'Result: $'
- remainder_msg db ' remainder $'
- newline db 13, 10, '$'
- cont_msg db 13, 10, 'Press ESC to exit or any key to continue...$'
- x dw ?
- result dw ?
- remainder dw ?
- buffer db 6, ?, 6 dup(?) ; Buffer for input: max length, actual length, characters
- is_negative db 0 ; Flag for negative input
- .code
- main proc
- mov ax, @data
- mov ds, ax
- ; Display title and equation system
- call display_equation_system
- main_loop:
- ; Display prompt
- mov ah, 09h
- lea dx, prompt_msg
- int 21h
- ; Get user input
- call read_number
- ; Check for input errors
- cmp ax, 0
- je error_handler
- ; Store x value
- mov x, bx
- ; Calculate Z based on the value of x
- call calculate_z
- ; Display result
- call display_result
- ; Check if user wants to continue
- mov ah, 09h
- lea dx, cont_msg
- int 21h
- ; Wait for key press
- mov ah, 01h
- int 21h
- ; If ESC pressed, exit
- cmp al, 27 ; ESC key scan code
- je exit_program
- ; Clear screen for next calculation
- call clear_screen
- ; Display equation system again
- call display_equation_system
- ; Continue loop
- jmp main_loop
- error_handler:
- mov ah, 09h
- lea dx, error_msg
- int 21h
- ; Check if user wants to continue
- mov ah, 09h
- lea dx, cont_msg
- int 21h
- ; Wait for key press
- mov ah, 01h
- int 21h
- ; If ESC pressed, exit
- cmp al, 27 ; ESC key scan code
- je exit_program
- ; Clear screen for next calculation
- call clear_screen
- ; Display equation system again
- call display_equation_system
- ; Continue loop
- jmp main_loop
- exit_program:
- ; Exit program
- mov ax, 4C00h
- int 21h
- main endp
- ; Procedure to display equation system and instructions
- display_equation_system proc
- mov ah, 09h
- lea dx, title_msg
- int 21h
- mov ah, 09h
- lea dx, equation_msg1
- int 21h
- mov ah, 09h
- lea dx, equation_msg2
- int 21h
- mov ah, 09h
- lea dx, equation_msg3
- int 21h
- mov ah, 09h
- lea dx, equation_msg4
- int 21h
- mov ah, 09h
- lea dx, instruction_msg
- int 21h
- ret
- display_equation_system endp
- ; Procedure to clear screen
- clear_screen proc
- mov ax, 0003h ; AH=0, AL=3 (text mode 80x25)
- int 10h
- ret
- clear_screen endp
- ; Procedure to read a number from user input
- read_number proc
- ; Read string
- mov ah, 0Ah
- lea dx, buffer
- int 21h
- ; Check if input is empty
- mov al, buffer[1]
- cmp al, 0
- je input_error
- ; Initialize registers
- xor bx, bx ; BX will hold the result
- mov cl, buffer[1] ; CL = length of input
- mov si, offset buffer + 2 ; SI points to first character
- ; Check for negative sign
- mov byte ptr [is_negative], 0
- cmp byte ptr [si], '-'
- jne check_digits
- ; Set negative flag and move to next character
- mov byte ptr [is_negative], 1
- inc si
- dec cl
- cmp cl, 0 ; Check if only minus sign was entered
- je input_error
- check_digits:
- ; Process each digit
- xor ax, ax
- mov al, [si]
- ; Check if character is a digit (0-9)
- cmp al, '0'
- jb input_error
- cmp al, '9'
- ja input_error
- ; Convert ASCII to numeric value
- sub al, '0'
- ; Multiply current result by 10 and add new digit
- mov dx, 10
- mov ax, bx
- mul dx
- jc check_overflow ; Check for overflow
- mov bx, ax
- mov al, [si]
- sub al, '0'
- ; Check for potential overflow before adding
- add bx, ax
- jc check_overflow ; Check for overflow
- ; Check for maximum/minimum 16-bit integer values
- cmp byte ptr [is_negative], 1
- je check_negative_limit
- cmp bx, 32767 ; Check max positive value for signed 16-bit
- ja check_overflow
- jmp continue_reading
- check_negative_limit:
- cmp bx, 32768 ; Check max negative value for signed 16-bit
- ja check_overflow
- continue_reading:
- ; Move to next character
- inc si
- dec cl
- jnz check_digits
- ; Apply negative sign if needed
- cmp byte ptr [is_negative], 1
- jne read_done
- neg bx
- read_done:
- mov ax, 1 ; Success
- ret
- check_overflow:
- ; Handle overflow - display error and wait for keypress
- mov ah, 09h
- lea dx, overflow_msg
- int 21h
- input_error:
- xor ax, ax ; Error
- ret
- read_number endp
- ; Procedure to calculate Z based on value of x
- calculate_z proc
- mov ax, x
- cmp ax, 10 ; Compare x with 10
- jl less_than_10
- je equal_to_10
- jg greater_than_10
- less_than_10:
- ; Z = x - 1
- mov ax, x
- dec ax
- mov result, ax
- mov remainder, 0
- ret
- equal_to_10:
- ; Z = (3x² + 4) / (x - 2)
- ; Check for division by zero
- mov ax, x
- sub ax, 2
- cmp ax, 0
- je division_by_zero
- ; Calculate 3x²
- mov ax, x
- imul ax ; AX = x²
- jo overflow_error
- mov bx, 3
- imul bx ; AX = 3x²
- jo overflow_error
- ; Add 4
- add ax, 4
- jo overflow_error
- ; Divide by (x - 2)
- mov bx, x
- sub bx, 2
- ; Perform division
- cwd ; Convert word to doubleword (sign extend AX into DX:AX)
- idiv bx ; AX = quotient, DX = remainder
- mov result, ax
- mov remainder, dx
- ret
- greater_than_10:
- ; Z = (7x² - 56) / (2x - 5)
- ; Check for division by zero
- mov ax, x
- shl ax, 1 ; AX = 2x
- sub ax, 5 ; AX = 2x - 5
- cmp ax, 0
- je division_by_zero
- mov bx, ax ; Store denominator in BX
- ; Calculate 7x²
- mov ax, x
- imul ax ; AX = x²
- jo overflow_error
- mov cx, 7
- imul cx ; AX = 7x²
- jo overflow_error
- ; Subtract 56
- sub ax, 56
- jo overflow_error
- ; Divide by (2x - 5)
- cwd ; Convert word to doubleword (sign extend AX into DX:AX)
- idiv bx ; AX = quotient, DX = remainder
- mov result, ax
- mov remainder, dx
- ret
- division_by_zero:
- mov ah, 09h
- lea dx, div_zero_msg
- int 21h
- ; Wait for key press to continue
- mov ah, 09h
- lea dx, cont_msg
- int 21h
- mov ah, 01h
- int 21h
- ; If ESC pressed, exit
- cmp al, 27 ; ESC key scan code
- je exit_div_zero
- ; Clear screen and display equation system
- call clear_screen
- call display_equation_system
- ; Return to main loop
- jmp main_loop
- exit_div_zero:
- mov ax, 4C01h ; Exit with error code
- int 21h
- overflow_error:
- mov ah, 09h
- lea dx, overflow_msg
- int 21h
- ; Wait for key press to continue
- mov ah, 09h
- lea dx, cont_msg
- int 21h
- mov ah, 01h
- int 21h
- ; If ESC pressed, exit
- cmp al, 27 ; ESC key scan code
- je exit_overflow
- ; Clear screen and display equation system
- call clear_screen
- call display_equation_system
- ; Return to main loop
- jmp main_loop
- exit_overflow:
- mov ax, 4C02h ; Exit with error code
- int 21h
- calculate_z endp
- ; Procedure to display calculation result
- display_result proc
- mov ah, 09h
- lea dx, result_msg
- int 21h
- ; Display quotient (result)
- mov ax, result
- call display_number
- ; Check if there's a remainder to display
- mov ax, remainder
- cmp ax, 0
- je no_remainder
- ; Display remainder part
- mov ah, 09h
- lea dx, remainder_msg
- int 21h
- mov ax, remainder
- call display_number
- no_remainder:
- mov ah, 09h
- lea dx, newline
- int 21h
- ret
- display_result endp
- ; Procedure to display a signed number
- display_number proc
- ; Check if number is negative
- test ax, ax
- jns positive_number
- ; Display minus sign
- push ax
- mov dl, '-'
- mov ah, 02h
- int 21h
- pop ax
- ; Convert to positive
- neg ax
- positive_number:
- ; Convert number to string
- mov bx, 10 ; Divisor
- mov cx, 0 ; Digit counter
- digit_loop:
- xor dx, dx
- div bx ; AX / 10: quotient in AX, remainder in DX
- push dx ; Push digit on stack
- inc cx ; Increment digit counter
- test ax, ax
- jnz digit_loop ; Continue if quotient is not zero
- display_loop:
- pop dx ; Get digit from stack
- add dl, '0' ; Convert to ASCII
- mov ah, 02h
- int 21h ; Display character
- loop display_loop
- ret
- display_number endp
- end main
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement