Advertisement
Artychenal

Untitled

Apr 10th, 2025 (edited)
896
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
6502 TASM/64TASS 22.65 KB | Source Code | 0 0
  1. DATA SEGMENT
  2.  
  3.     ; --- Новий текст із описом функції ---
  4.     messtr          DB 0Dh,0Ah, "Welcome! Let`s solve the piecewise function Z with your X value", 0Dh,0Ah,"$"
  5.  
  6.     ; Опис нової функції
  7.     funct           DB "Z = { x-1, if x < 10", 0Dh,0Ah, " { (3x^2 + 4)/(x - 2), if x = 10", 0Dh,0Ah," { (7x^2 - 56)/(2x - 5), if x > 10", 0Dh,0Ah,"$"
  8.  
  9.     xreadmes        DB "Input value of x (in range -32767...32767) -> $"                                                                                 ; Змінено діапазон для точності
  10.  
  11.     numoverflow_msg DB "Numerator overflow during calculation!", 0Dh,0Ah, "$"
  12.  
  13.     ; Буфер для введення X
  14.     xinmes          DB 7,?,7 DUP(" ")
  15.  
  16.     ; Прапорець знаку
  17.     sign_flag       DB 0
  18.  
  19.     ; Змінні, у яких зберігається вхідне X
  20.     xvalue          DW ?
  21.  
  22.     ; Повідомлення про результат
  23.     outmes          DB "Result: $"
  24.     newline         DB 0Dh,0Ah,"$"
  25.     errmsg          DB 0Dh,0Ah,"Invalid input!",0Dh,0Ah,"$"
  26.     range_err       DB "Number out of range!",0Dh,0Ah,"$"
  27.     ostacha_msg     DB " reminder $"
  28.     end_msg         DB "Do you want to continue? (y/n): $"
  29.  
  30.     ; Змінні для зберігання проміжних результатів
  31.     result          DW ?
  32.     remainder       DW ?
  33.     numerator       DW ?
  34.     denominator     DW ?
  35.  
  36.     ; Буфер для 'y/n'
  37.     menuhold        DB 2,0,2 DUP(" ")
  38.  
  39. DATA ENDS
  40.  
  41. ; Сегмент стеку
  42. STSEG SEGMENT PARA STACK 'STACK'
  43.           DB 64 DUP ("STACK")
  44. STSEG ENDS
  45.  
  46. CODE SEGMENT
  47.                           ASSUME CS:CODE, DS:DATA, SS:STSEG
  48.  
  49.     START:                
  50.                           MOV    AX, DATA
  51.                           MOV    DS, AX
  52.  
  53.     ; Вітання і читання X
  54.                           CALL   WELC_PROC
  55.    
  56.     ; Обчислення нашої кусочної функції
  57.                           CALL   FUNC
  58.  
  59.     ; Виведення результату
  60.                           CALL   PRINTING
  61.  
  62.     ; Запит на продовження або вихід
  63.                           CALL   END_PROGRAM
  64.  
  65.     ; Повернення управління в DOS
  66.                           MOV    AH, 10
  67.                           INT    21h
  68.  
  69.     ;----------------------------------------
  70.     ; Процедура вітання і зчитування X
  71.     ;----------------------------------------
  72. WELC_PROC PROC
  73.     ; Вивести вітальний рядок
  74.                           MOV    DX, OFFSET messtr
  75.                           MOV    AH, 9
  76.                           INT    21h
  77.  
  78.     ; Вивести опис функції
  79.                           MOV    DX, OFFSET funct
  80.                           MOV    AH, 9
  81.                           INT    21h
  82.  
  83.     ; Запропонувати ввести X
  84.                           MOV    DX, OFFSET xreadmes
  85.                           MOV    AH, 9
  86.                           INT    21h
  87.  
  88.     ; Зчитати X (рядок)
  89.                           MOV    DX, OFFSET xinmes
  90.                           MOV    AH, 10
  91.                           INT    21h
  92.  
  93.     ; Перевірка, чи коректний введений рядок
  94.                           CALL   CHECK_INPUT
  95.  
  96.     ; Конвертувати з ACSII у число xvalue
  97.                           MOV    SI, OFFSET xinmes
  98.                           ADD    SI, 2
  99.                           CALL   CONVERT
  100.                           MOV    xvalue, BX
  101.  
  102.     ; Перехід на новий рядок
  103.                           MOV    DX, OFFSET newline
  104.                           MOV    AH, 9
  105.                           INT    21h
  106.  
  107.                           RET
  108. WELC_PROC ENDP
  109.  
  110.     ;----------------------------------------
  111.     ; Перевірка введених символів на коректність
  112.     ;----------------------------------------
  113. CHECK_INPUT PROC
  114.                           MOV    SI, DX                        ; DX = OFFSET xinmes
  115.                           MOV    CL, [SI+1]                    ; CL = довжина введеного рядка
  116.                           MOV    BL, 0
  117.                           ADD    SI, 2
  118.  
  119.                           MOV    AL, [SI]
  120.                           CMP    AL, '-'
  121.                           JNE    CHECK_DIGITS
  122.                           MOV    sign_flag, 1
  123.                           INC    SI
  124.                           DEC    CX
  125.                           JZ     INVALID_INPUT
  126.  
  127.  
  128.     CHECK_DIGITS:        
  129.                           CMP    CX, 0
  130.                           JZ     END_CHECK
  131.  
  132.     CHECK_LOOP:          
  133.                           MOV    AL, [SI]
  134.                           CMP    AL, '0'
  135.                           JB     INVALID_INPUT
  136.                           CMP    AL, '9'
  137.                           JA     INVALID_INPUT
  138.  
  139.                           INC    BL
  140.                           INC    SI
  141.                           DEC    CX
  142.                           JNZ    CHECK_LOOP
  143.  
  144.                           CMP    BL, 0
  145.                           JZ     INVALID_INPUT
  146.                           JMP    END_CHECK
  147.  
  148.     INVALID_INPUT:        
  149.                           MOV    DX, OFFSET errmsg
  150.                           MOV    AH, 9
  151.                           INT    21h
  152.                           JMP    START
  153.  
  154.     END_CHECK:            
  155.                           RET
  156. CHECK_INPUT ENDP
  157.  
  158.     ;----------------------------------------
  159.     ; Процедура перевірки X на вихід за межі
  160.     ;----------------------------------------
  161. CHECK_RANGE PROC
  162.                           CMP    sign_flag, 0
  163.                           JE     CHECK_POSITIVE_RANGE
  164.  
  165.                           CMP    AX, -32767
  166.                           JL     RANGE_ERROR
  167.                           JC     RANGE_ERROR
  168.                           RET
  169.  
  170.     CHECK_POSITIVE_RANGE:
  171.                           CMP    AX, 32767                     ; Змінено з 32767 на 32767 для коректної перевірки
  172.                           JG     RANGE_ERROR
  173.                           RET
  174.  
  175.     RANGE_ERROR:          
  176.                           MOV    DX, OFFSET newline
  177.                           MOV    AH, 9
  178.                           INT    21h
  179.  
  180.                           MOV    DX, OFFSET range_err
  181.                           MOV    AH, 9
  182.                           INT    21h
  183.  
  184.                           JMP    START
  185.  
  186. CHECK_RANGE ENDP
  187.  
  188.     ;----------------------------------------
  189.     ; Перевірка чисельника на переповнення
  190.     ;----------------------------------------
  191. CHECK_NUMERATOR PROC
  192.                           MOV    AX, numerator
  193.                           CMP    AX, -32768
  194.                           JL     NUM_OVERFLOW
  195.                           CMP    AX, 32767
  196.                           JG     NUM_OVERFLOW
  197.                           RET
  198.  
  199.     NUM_OVERFLOW:        
  200.                           MOV    DX, OFFSET newline
  201.                           MOV    AH, 9
  202.                           INT    21h
  203.                           MOV    DX, OFFSET numoverflow_msg
  204.                           MOV    AH, 9
  205.                           INT    21h
  206.                           JMP    START
  207. CHECK_NUMERATOR ENDP
  208.  
  209.  
  210.     ;----------------------------------------
  211.     ; Перевірка результату (за потреби)
  212.     ;----------------------------------------
  213. CHECK_RANGE_RESULT PROC
  214.                           MOV    AX, result
  215.                           CMP    AX, -32768
  216.                           JL     RANGE_ERROR_RES
  217.                           CMP    AX, 32767
  218.                           JG     RANGE_ERROR_RES
  219.                           RET
  220.  
  221.     RANGE_ERROR_RES:      
  222.                           MOV    DX, OFFSET newline
  223.                           MOV    AH, 9
  224.                           INT    21h
  225.                           MOV    DX, OFFSET range_err
  226.                           MOV    AH, 9
  227.                           INT    21h
  228.                           JMP    START
  229. CHECK_RANGE_RESULT ENDP
  230.  
  231.  
  232. CHECK_NUM_DENOM PROC
  233.     ; Перевірка чисельника
  234.                           MOV    AX, numerator
  235.                           CMP    AX, -32768
  236.                           JL     RANGE_ERROR_ND
  237.                           CMP    AX, 32767
  238.                           JG     RANGE_ERROR_ND
  239.  
  240.     ; Перевірка знаменника на діапазон
  241.                           MOV    AX, denominator
  242.                           CMP    AX, -32768
  243.                           JL     RANGE_ERROR_ND
  244.                           CMP    AX, 32767
  245.                           JG     RANGE_ERROR_ND
  246.  
  247.     ; Перевірка ділення на нуль
  248.                           CMP    AX, 0                         ; Додана перевірка ділення на нуль
  249.                           JE     RANGE_ERROR_ND
  250.                           RET
  251.  
  252.     RANGE_ERROR_ND:      
  253.                           MOV    DX, OFFSET newline
  254.                           MOV    AH, 9
  255.                           INT    21h
  256.                           MOV    DX, OFFSET range_err
  257.                           MOV    AH, 9
  258.                           INT    21h
  259.                           JMP    START
  260.  
  261. CHECK_NUM_DENOM ENDP
  262.  
  263.  
  264.     ;----------------------------------------
  265.     ; Перетворення введеної ASCII-послідовності
  266.     ; в число (AX)
  267.     ;----------------------------------------
  268. CONVERT PROC
  269.                           XOR    AX, AX
  270.                           XOR    BX, BX
  271.                           PUSH   AX
  272.                           PUSH   BX
  273.                           PUSH   CX
  274.                           PUSH   DX
  275.  
  276.                           MOV    BX, 0
  277.  
  278.                           CMP    sign_flag, 1
  279.                           JNE    CONVERT_LOOP
  280.                           INC    SI
  281.  
  282.     CONVERT_LOOP:        
  283.                           MOV    AL, [SI]
  284.                           CMP    AL, '0'
  285.                           JB     CONVERT_END
  286.                           CMP    AL, '9'
  287.                           JA     CONVERT_END
  288.                           SUB    AL, '0'
  289.                           MOV    AH, 0
  290.                           PUSH   AX
  291.  
  292.                           MOV    AX, BX
  293.                           MOV    CX, 10
  294.                           MUL    CX
  295.                           CMP    DX, 0
  296.                           JNE    OVERFLOW_ERROR
  297.                           MOV    BX, AX
  298.  
  299.                           POP    AX
  300.                           ADD    BX, AX
  301.                           JC     OVERFLOW_ERROR                ; Додана перевірка на переповнення після додавання
  302.                           INC    SI
  303.                           JMP    CONVERT_LOOP
  304.  
  305.     OVERFLOW_ERROR:      
  306.                           MOV    DX, OFFSET newline
  307.                           MOV    AH, 9
  308.                           INT    21h
  309.                           MOV    DX, OFFSET range_err
  310.                           MOV    AH, 9
  311.                           INT    21h
  312.                           JMP    START
  313.  
  314.     CONVERT_END:          
  315.     ; ОДИН раз робимо NEG BX, якщо sign_flag=1
  316.                           CMP    sign_flag, 1
  317.                           JNE    CONVERT_FINISH
  318.                           NEG    BX
  319.                           JO     OVERFLOW_ERROR                ; Додана перевірка на переповнення після NEG
  320.  
  321.     CONVERT_FINISH:      
  322.                           MOV    AX, BX
  323.                           CALL   CHECK_RANGE
  324.  
  325.                           POP    DX
  326.                           POP    CX
  327.                           POP    BX
  328.                           MOV    BX, AX
  329.                           POP    AX
  330.                           RET
  331. CONVERT ENDP
  332.  
  333.     ;----------------------------------------
  334.     ; Основна процедура обчислення Z
  335.     ;----------------------------------------
  336. FUNC PROC
  337.                           XOR    AX, AX
  338.                           MOV    AX, xvalue
  339.  
  340.                           CMP    AX, 10
  341.                           JL     CASE_X_LT_10
  342.                           JE     CASE_X_EQ_10
  343.                           JG     CASE_X_GT_10
  344.  
  345.     CASE_X_LT_10:        
  346.     ; Z = x - 1
  347.                           MOV    AX, xvalue
  348.                           DEC    AX
  349.                           JO     CASE_X_LT_10_OVERFLOW         ; Додана перевірка на переповнення
  350.                           MOV    result, AX
  351.                           MOV    remainder, 0
  352.                           JMP    END_FUNC
  353.  
  354.     CASE_X_LT_10_OVERFLOW:
  355.                           MOV    DX, OFFSET numoverflow_msg
  356.                           MOV    AH, 9
  357.                           INT    21h
  358.                           JMP    START
  359.  
  360.     CASE_X_EQ_10:        
  361.     ; Z = (3x^2 + 4)/(x - 2)
  362.                           MOV    AX, xvalue
  363.                           IMUL   xvalue                        ; DX:AX = x^2 (результат в DX:AX)
  364.                          
  365.                           MOV    BX, 3
  366.                           IMUL   BX                            ; DX:AX = 3x^2
  367.                          
  368.                           ADD    AX, 4                         ; AX = 3x^2 + 4
  369.                           MOV    numerator, AX
  370.  
  371.                           MOV    AX, xvalue
  372.                           SUB    AX, 2
  373.                           MOV    denominator, AX
  374.  
  375.                           CALL   CHECK_NUM_DENOM
  376.  
  377.                           MOV    AX, numerator
  378.                           CWD
  379.                           MOV    BX, denominator
  380.                           IDIV   BX
  381.  
  382.                           MOV    result, AX
  383.                           MOV    remainder, DX
  384.                           JMP    END_FUNC
  385.  
  386.     CASE_X_GT_10:        
  387.     ; Z = (7x^2 - 56)/(2x - 5)
  388.                           MOV    AX, xvalue
  389.                           IMUL   xvalue                        ; DX:AX = x^2 (результат в DX:AX)
  390.                          
  391.     ; Перевірка переповнення після першого множення
  392.                           CMP    DX, 0
  393.                           JNE    NUM_OVERFLOW_GT10
  394.                          
  395.                           MOV    BX, 7
  396.                           IMUL   BX                            ; DX:AX = 7x^2
  397.                          
  398.     ; Перевірка переповнення після другого множення
  399.                           CMP    DX, 0
  400.                           JNE    NUM_OVERFLOW_GT10
  401.                          
  402.                           SUB    AX, 56                        ; AX = 7x^2 - 56
  403.                           JO     NUM_OVERFLOW_GT10             ; Додана перевірка на переповнення після віднімання
  404.                           MOV    numerator, AX
  405.                           CALL   CHECK_NUMERATOR
  406.  
  407.                           MOV    AX, xvalue
  408.                           SHL    AX, 1                         ; AX = 2x
  409.                           JO     NUM_OVERFLOW_GT10             ; Додана перевірка на переповнення після зсуву
  410.                           SUB    AX, 5                         ; AX = 2x - 5
  411.                           JO     NUM_OVERFLOW_GT10             ; Додана перевірка на переповнення після віднімання
  412.                           MOV    denominator, AX
  413.  
  414.                           CALL   CHECK_NUM_DENOM
  415.  
  416.                           MOV    AX, numerator
  417.                           CWD
  418.                           MOV    BX, denominator
  419.                           IDIV   BX
  420.  
  421.                           MOV    result, AX
  422.                           MOV    remainder, DX
  423.                           CALL   CHECK_RANGE_RESULT
  424.                           JMP    END_FUNC
  425.  
  426.     NUM_OVERFLOW_GT10:    
  427.                           MOV    DX, OFFSET newline
  428.                           MOV    AH, 9
  429.                           INT    21h
  430.                           MOV    DX, OFFSET numoverflow_msg
  431.                           MOV    AH, 9
  432.                           INT    21h
  433.                           JMP    START
  434.  
  435.     END_FUNC:            
  436.                           RET
  437. FUNC ENDP
  438.  
  439.  
  440.     ;----------------------------------------
  441.     ; Друк результату
  442.     ;----------------------------------------
  443. PRINTING PROC
  444.     ; Перенос на новий рядок
  445.                           MOV    DX, OFFSET newline
  446.                           MOV    AH, 9
  447.                           INT    21h
  448.  
  449.     ; "Result:"
  450.                           MOV    DX, OFFSET outmes
  451.                           MOV    AH, 9
  452.                           INT    21h
  453.  
  454.     ; Якщо remainder=0, це ціле
  455.                           MOV    AX, remainder
  456.                           CMP    AX, 0
  457.                           JNE    PRINT_FRACTION
  458.  
  459.     ; Якщо результат від'ємний -> "-"
  460.                           MOV    AX, result
  461.                           CMP    AX, 0
  462.                           JGE    PRINT_MAIN_NUMBER
  463.                           MOV    DL, '-'
  464.                           MOV    AH, 2
  465.                           INT    21h
  466.  
  467.                           MOV    AX, result
  468.                           NEG    AX
  469.  
  470.     PRINT_MAIN_NUMBER:    
  471.                           CALL   PRINT_NUM
  472.                           JMP    END_PRINTING
  473.  
  474.     PRINT_FRACTION:      
  475.     ; Виводимо вигляд: numerator / denominator = result reminder remainder
  476.                           MOV    AX, numerator
  477.                           CMP    AX, 0
  478.                           JGE    PRINT_NUMERATOR
  479.                           MOV    DL, '-'
  480.                           MOV    AH, 2
  481.                           INT    21h
  482.                           MOV    AX, numerator
  483.                           NEG    AX
  484.  
  485.     PRINT_NUMERATOR:      
  486.                           CALL   PRINT_NUM
  487.  
  488.                           MOV    DL, '/'
  489.                           MOV    AH, 2
  490.                           INT    21h
  491.  
  492.                           MOV    AX, denominator
  493.                           CMP    AX, 0
  494.                           JGE    PRINT_DENOM
  495.                           MOV    DL, '-'
  496.                           MOV    AH, 2
  497.                           INT    21h
  498.                           MOV    AX, denominator
  499.                           NEG    AX
  500.  
  501.     PRINT_DENOM:          
  502.                           CALL   PRINT_NUM
  503.  
  504.                           MOV    DL, ' '
  505.                           MOV    AH, 2
  506.                           INT    21h
  507.  
  508.                           MOV    DL, '='
  509.                           INT    21h
  510.                           MOV    DL, ' '
  511.                           INT    21h
  512.  
  513.                           MOV    AX, result
  514.                           CMP    AX, 0
  515.                           JGE    PRINT_RES_NUMBER
  516.                           MOV    DL, '-'
  517.                           MOV    AH, 2
  518.                           INT    21h
  519.                           MOV    AX, result
  520.                           NEG    AX
  521.  
  522.     PRINT_RES_NUMBER:    
  523.                           CALL   PRINT_NUM
  524.  
  525.                           MOV    DX, OFFSET ostacha_msg
  526.                           MOV    AH, 9
  527.                           INT    21h
  528.  
  529.                           MOV    AX, remainder
  530.                           CMP    AX, 0
  531.                           JGE    PRINT_REMAINDER
  532.                           MOV    DL, '-'
  533.                           MOV    AH, 2
  534.                           INT    21h
  535.                           MOV    AX, remainder
  536.                           NEG    AX
  537.  
  538.     PRINT_REMAINDER:      
  539.                           CALL   PRINT_NUM
  540.                           JMP    END_PRINTING
  541.  
  542.     END_PRINTING:        
  543.                           RET
  544. PRINTING ENDP
  545.  
  546.     ;----------------------------------------
  547.     ; Процедура PRINT_NUM: виводить число (AX)
  548.     ;----------------------------------------
  549. PRINT_NUM PROC
  550.                           PUSH   result
  551.                           PUSH   CX
  552.                           PUSH   DX
  553.  
  554.                           XOR    CX, CX
  555.                           MOV    BX, 10
  556.  
  557.     CONVERT_TO_STR:      
  558.                           XOR    DX, DX
  559.                           DIV    BX
  560.                           ADD    DL, '0'
  561.                           PUSH   DX
  562.                           INC    CX
  563.                           TEST   AX, AX
  564.                           JNZ    CONVERT_TO_STR
  565.  
  566.     PRINT_LOOP:          
  567.                           POP    DX
  568.                           MOV    AH, 2
  569.                           INT    21h
  570.                           LOOP   PRINT_LOOP
  571.  
  572.                           POP    DX
  573.                           POP    CX
  574.                           POP    result
  575.                           RET
  576. PRINT_NUM ENDP
  577.  
  578.     ;----------------------------------------
  579.     ; Запит, чи продовжувати?
  580.     ;----------------------------------------
  581. END_PROGRAM PROC
  582.                           MOV    DX, OFFSET newline
  583.                           MOV    AH, 9
  584.                           INT    21h
  585.  
  586.                           MOV    DX, OFFSET end_msg
  587.                           MOV    AH, 9
  588.                           INT    21h
  589.  
  590.                           MOV    DX, OFFSET menuhold
  591.                           MOV    AH, 0Ah
  592.                           INT    21h
  593.  
  594.                           MOV    AL, menuhold+2
  595.                           CMP    AL, 'y'
  596.                           JE     RETURN
  597.                           CMP    AL, 'n'
  598.                           JE     EXIT_PROGRAM
  599.  
  600.                           MOV    DX, OFFSET errmsg
  601.                           MOV    AH, 9
  602.                           INT    21h
  603.                           JMP    END_PROGRAM
  604.  
  605.     EXIT_PROGRAM:        
  606.                           MOV    AH, 4Ch
  607.                           INT    21h
  608.  
  609.     RETURN:              
  610.                           XOR    AX,AX
  611.                           XOR    BX,BX
  612.                           XOR    CX,CX
  613.                           XOR    DX,DX
  614.                           XOR    SI,SI
  615.  
  616.                           MOV    result, 0
  617.                           MOV    remainder, 0
  618.                           MOV    numerator, 0
  619.                           MOV    denominator, 0
  620.                           MOV    sign_flag, 0
  621.  
  622.     ; Переходимо до START для перезапуску програми
  623.                           JMP    START
  624.  
  625. END_PROGRAM ENDP
  626.  
  627. CODE ENDS
  628. END START
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement