Advertisement
Artychenal

Untitled

Apr 8th, 2025
38
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 16.87 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 -32768...32767) -> $"
  10.  
  11. ; Буфер для введення X
  12. ; Замість 7,?,7 => 7,0,7. Перший байт = максимально дозволена довжина,
  13. ; другий = актуальна довжина (0 поки що), решта 7 символів = місце для вводу
  14. xinmes DB 7,0,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' (так само замінюємо ? на 0)
  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.  
  163. ; -32768 <= AX <= 32767
  164. CMP AX, 32767
  165. JG RANGE_ERROR ; якщо AX > 32767 => помилка
  166. CMP AX, -32768
  167. JL RANGE_ERROR ; якщо AX < -32768 => помилка
  168. RET
  169.  
  170. RANGE_ERROR:
  171. MOV DX, OFFSET range_err
  172. MOV AH, 9
  173. INT 21h
  174.  
  175. RET
  176. CHECK_RANGE ENDP
  177.  
  178. ;----------------------------------------
  179. ; Перевірка результату (за потреби)
  180. ;----------------------------------------
  181. CHECK_RANGE_RESULT PROC
  182. MOV AX, result
  183. CMP AX, -32768
  184. JA RANGE_ERROR_RES
  185. CMP AX, 32752
  186. JG RANGE_ERROR_RES
  187. RET
  188.  
  189. RANGE_ERROR_RES:
  190. MOV DX, OFFSET newline
  191. MOV AH, 9
  192. INT 21h
  193. MOV DX, OFFSET range_err
  194. MOV AH, 9
  195. INT 21h
  196. JMP START
  197. CHECK_RANGE_RESULT ENDP
  198.  
  199. ;----------------------------------------
  200. ; Перетворення введеної ASCII-послідовності
  201. ; в число (AX)
  202. ;----------------------------------------
  203. CONVERT PROC
  204. XOR AX, AX
  205. XOR BX, BX
  206. PUSH AX
  207. PUSH BX
  208. PUSH CX
  209. PUSH DX
  210.  
  211. MOV BX, 0
  212.  
  213. CMP sign_flag, 1
  214. JNE CONVERT_LOOP
  215.  
  216. CONVERT_LOOP:
  217. MOV AL, [SI]
  218. CMP AL, '0'
  219. JB CONVERT_END
  220. CMP AL, '9'
  221. JA CONVERT_END
  222. SUB AL, '0'
  223. MOV AH, 0
  224. PUSH AX
  225.  
  226. MOV AX, BX
  227. MOV CX, 10
  228. MUL CX
  229. CMP DX, 0
  230. JNE OVERFLOW_ERROR
  231. MOV BX, AX
  232.  
  233. POP AX
  234. ADD BX, AX
  235. INC SI
  236. JMP CONVERT_LOOP
  237.  
  238. OVERFLOW_ERROR:
  239. MOV DX, OFFSET newline
  240. MOV AH, 9
  241. INT 21h
  242. MOV DX, OFFSET range_err
  243. MOV AH, 9
  244. INT 21h
  245. JMP START
  246.  
  247. CONVERT_END:
  248. ; ОДИН раз робимо NEG BX, якщо sign_flag=1
  249. CMP sign_flag, 1
  250. JNE CONVERT_FINISH
  251. NEG BX
  252.  
  253. CONVERT_FINISH:
  254. MOV AX, BX
  255. CALL CHECK_RANGE
  256.  
  257. POP DX
  258. POP CX
  259. POP BX
  260. MOV BX, AX
  261. POP AX
  262. RET
  263. CONVERT ENDP
  264.  
  265. ;----------------------------------------
  266. ; Основна процедура обчислення Z
  267. ;----------------------------------------
  268. FUNC PROC
  269. XOR AX, AX
  270. MOV AX, xvalue
  271.  
  272. ; Перевіряємо, де ми знаходимося
  273. CMP AX, 10
  274. JL CASE_X_LT_10 ; x < 10
  275. JE CASE_X_EQ_10 ; x = 10
  276. JG CASE_X_GT_10 ; x > 10
  277.  
  278. CASE_X_LT_10:
  279. ; Z = x - 1
  280. MOV AX, xvalue
  281. DEC AX
  282. MOV result, AX
  283. MOV remainder, 0
  284. JMP END_FUNC
  285.  
  286. CASE_X_EQ_10:
  287. ; Z = (3x^2 + 4)/(x - 2), при x=10
  288. ; Чисельник = 3*(10^2) + 4 = 304
  289. ; Знаменник = 10 - 2 = 8
  290. MOV AX, xvalue
  291. IMUL xvalue
  292. MOV BX, 3
  293. IMUL BX
  294. ADD AX, 4
  295. MOV numerator, AX
  296.  
  297. MOV AX, 10
  298. SUB AX, 2
  299. MOV denominator, AX
  300.  
  301. MOV AX, numerator
  302. CWD
  303. MOV BX, denominator
  304. IDIV BX
  305.  
  306. MOV result, AX
  307. MOV remainder, DX
  308. CALL CHECK_RANGE_RESULT
  309. JMP END_FUNC
  310.  
  311. CASE_X_GT_10:
  312. ; Z = (7x^2 - 56)/(2x - 5)
  313. MOV AX, xvalue
  314. IMUL xvalue ; x^2
  315. MOV BX, 7
  316. IMUL BX ; 7*x^2
  317. SUB AX, 56 ; 7x^2 - 56
  318. MOV numerator, AX
  319.  
  320. MOV AX, xvalue
  321. SHL AX, 1 ; 2*x
  322. SUB AX, 5 ; 2x - 5
  323. MOV denominator, AX
  324.  
  325. MOV AX, numerator
  326. CWD
  327. MOV BX, denominator
  328. IDIV BX
  329.  
  330. MOV result, AX
  331. MOV remainder, DX
  332. CALL CHECK_RANGE_RESULT
  333. JMP END_FUNC
  334.  
  335. END_FUNC:
  336. RET
  337. FUNC ENDP
  338.  
  339. ;----------------------------------------
  340. ; Друк результату
  341. ;----------------------------------------
  342. PRINTING PROC
  343. ; Перенос на новий рядок
  344. MOV DX, OFFSET newline
  345. MOV AH, 9
  346. INT 21h
  347.  
  348. ; "Result:"
  349. MOV DX, OFFSET outmes
  350. MOV AH, 9
  351. INT 21h
  352.  
  353. ; Якщо remainder=0, це ціле
  354. MOV AX, remainder
  355. CMP AX, 0
  356. JNE PRINT_FRACTION
  357.  
  358. ; Якщо результат від’ємний -> "-"
  359. MOV AX, result
  360. CMP AX, 0
  361. JGE PRINT_MAIN_NUMBER
  362. MOV DL, '-'
  363. MOV AH, 2
  364. INT 21h
  365.  
  366. PRINT_MAIN_NUMBER:
  367. CALL PRINT_NUM
  368. JMP END_PRINTING
  369.  
  370. PRINT_FRACTION:
  371. ; Виводимо вигляд: numerator / denominator = result reminder remainder
  372. MOV AX, numerator
  373. CMP AX, 0
  374. JGE PRINT_NUMERATOR
  375. MOV DL, '-'
  376. MOV AH, 2
  377. INT 21h
  378.  
  379. PRINT_NUMERATOR:
  380. CALL PRINT_NUM
  381.  
  382. MOV DL, '/'
  383. MOV AH, 2
  384. INT 21h
  385.  
  386. MOV AX, denominator
  387. CALL PRINT_NUM
  388.  
  389. MOV DL, ' '
  390. MOV AH, 2
  391. INT 21h
  392.  
  393. MOV DL, '='
  394. INT 21h
  395. MOV DL, ' '
  396. INT 21h
  397.  
  398. MOV AX, result
  399. CMP AX, 0
  400. JGE PRINT_RES_NUMBER
  401. MOV DL, '-'
  402. MOV AH, 2
  403. INT 21h
  404.  
  405. PRINT_RES_NUMBER:
  406. CALL PRINT_NUM
  407.  
  408. MOV DX, OFFSET ostacha_msg
  409. MOV AH, 9
  410. INT 21h
  411.  
  412. MOV AX, remainder
  413. CMP AX, 0
  414. JL NEG_NUM
  415. CALL PRINT_NUM
  416. JMP END_PRINTING
  417.  
  418. NEG_NUM:
  419. NEG AX
  420. CALL PRINT_NUM
  421.  
  422. END_PRINTING:
  423. RET
  424. PRINTING ENDP
  425.  
  426. ;----------------------------------------
  427. ; Процедура PRINT_NUM: виводить число (AX)
  428. ;----------------------------------------
  429. PRINT_NUM PROC
  430. PUSH result
  431. PUSH CX
  432. PUSH DX
  433.  
  434. XOR CX, CX
  435. MOV BX, 10
  436.  
  437. CONVERT_TO_STR:
  438. XOR DX, DX
  439. DIV BX
  440. ADD DL, '0'
  441. PUSH DX
  442. INC CX
  443. TEST AX, AX
  444. JNZ CONVERT_TO_STR
  445.  
  446. PRINT_LOOP:
  447. POP DX
  448. MOV AH, 2
  449. INT 21h
  450. LOOP PRINT_LOOP
  451.  
  452. POP DX
  453. POP CX
  454. POP result
  455. RET
  456. PRINT_NUM ENDP
  457.  
  458. ;----------------------------------------
  459. ; Запит, чи продовжувати?
  460. ;----------------------------------------
  461. END_PROGRAM PROC
  462. MOV DX, OFFSET newline
  463. MOV AH, 9
  464. INT 21h
  465.  
  466. MOV DX, OFFSET end_msg
  467. MOV AH, 9
  468. INT 21h
  469.  
  470. MOV DX, OFFSET menuhold
  471. MOV AH, 0Ah
  472. INT 21h
  473.  
  474. MOV AL, menuhold+2
  475. CMP AL, 'y'
  476. JE RETURN
  477. CMP AL, 'n'
  478. JE EXIT_PROGRAM
  479.  
  480. MOV DX, OFFSET errmsg
  481. MOV AH, 9
  482. INT 21h
  483. JMP END_PROGRAM
  484.  
  485. EXIT_PROGRAM:
  486. MOV AH, 4Ch
  487. INT 21h
  488.  
  489. RETURN:
  490. XOR AX,AX
  491. XOR BX,BX
  492. XOR CX,CX
  493. XOR DX,DX
  494. XOR SI,SI
  495.  
  496. MOV result, 0
  497. MOV remainder, 0
  498. MOV numerator, 0
  499. MOV denominator, 0
  500. MOV sign_flag, 0
  501.  
  502. ; Перезапускаємо програму
  503. CALL RET_PROC
  504. RET
  505. END_PROGRAM ENDP
  506.  
  507. ; Псевдо "повернення" у START
  508. RET_PROC PROC
  509. CALL START
  510. RET
  511. RET_PROC ENDP
  512.  
  513. CODE ENDS
  514. END START
  515.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement