Advertisement
Guest User

Untitled

a guest
May 31st, 2016
138
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.24 KB | None | 0 0
  1. .model small
  2.  
  3. .stack 100h
  4.  
  5. .data
  6. ten dw 10
  7. FirstNumber dw 0
  8. SecondNumber dw 0
  9. TempVal1 dw 0
  10. TempVal2 dw 0
  11.  
  12. .code
  13. ; this macro prints a string that is given as a parameter, example:
  14. ; PRINTN 'hello world!'
  15. ; the same as PRINT, but new line is automatically added.
  16. PRINTN MACRO sdat
  17. LOCAL next_char, s_dcl, printed, skip_dcl
  18.  
  19. PUSH AX ; store registers...
  20. PUSH SI ;
  21.  
  22. JMP skip_dcl ; skip declaration.
  23. s_dcl DB sdat, 0Dh,0Ah, 0
  24.  
  25. skip_dcl:
  26. LEA SI, s_dcl
  27.  
  28. next_char:
  29. MOV AL, CS:[SI]
  30. CMP AL, 0
  31. JZ printed
  32. INC SI
  33. MOV AH, 0Eh ; teletype function.
  34. INT 10h
  35. JMP next_char
  36. printed:
  37.  
  38. POP SI ; re-store registers...
  39. POP AX ;
  40. ENDM
  41.  
  42. PRINT MACRO sdat
  43. LOCAL next_char, s_dcl, printed, skip_dcl
  44.  
  45. PUSH AX ; store registers...
  46. PUSH SI ;
  47.  
  48. JMP skip_dcl ; skip declaration.
  49. s_dcl DB sdat, 0
  50.  
  51. skip_dcl:
  52. LEA SI, s_dcl
  53.  
  54. next_char:
  55. MOV AL, CS:[SI]
  56. CMP AL, 0
  57. JZ printed
  58. INC SI
  59. MOV AH, 0Eh ; teletype function.
  60. INT 10h
  61. JMP next_char
  62. printed:
  63.  
  64. POP SI ; re-store registers...
  65. POP AX ;
  66. ENDM
  67.  
  68. ; this macro prints a char in AL and advances
  69. ; the current cursor position:
  70. PUTC MACRO char
  71. PUSH AX
  72. MOV AL, char
  73. MOV AH, 0Eh
  74. INT 10h
  75. POP AX
  76. ENDM
  77. MAIN PROC
  78.  
  79. call init
  80. call clearScreen
  81.  
  82. printn 'Zakres liczbowy 0-32765'
  83.  
  84. print 'Wpisz pierwsza liczbe: '
  85. call scan_num
  86.  
  87. mov FirstNumber, cx
  88. xor cx, cx
  89.  
  90. call printNewLine
  91.  
  92. print 'Wpisz druga liczbe: '
  93. call scan_num
  94. mov SecondNumber, cx
  95. xor cx, cx
  96.  
  97. call printNewLine
  98.  
  99. printn '(x1+(x1-x2): '
  100. call printAddNumbers
  101. call printNewLine
  102.  
  103.  
  104. jmp EndOfProgram
  105.  
  106. clearRegisters:
  107. xor ax, ax
  108. xor bx, bx
  109. xor cx, cx
  110. ret
  111.  
  112. printAddNumbers:
  113. call clearRegisters
  114.  
  115. ; (x1-x2)
  116. mov cx, FirstNumber
  117. mov TempVal1, cx
  118. sub cx, SecondNumber
  119. mov TempVal2, cx ; wynik x1 - x2
  120. xor cx, cx
  121.  
  122. ; cx + tempVal1
  123. mov cx, TempVal1
  124. add cx, TempVal2
  125.  
  126. mov ax, cx
  127. xor cx, cx
  128. call print_num
  129. ret
  130.  
  131. printNewLine:
  132. mov ah, 2
  133.  
  134. mov dl, 13
  135. int 21h
  136.  
  137. mov dl, 10
  138. int 21h
  139. ret
  140.  
  141. init:
  142. mov ax, @data
  143. mov ds, ax
  144. ret
  145.  
  146. clearScreen:
  147. mov ax, 3
  148. int 10h
  149. ret
  150.  
  151. EndOfProgram:
  152. mov ah, 4ch
  153. int 21h
  154. ret
  155. MAIN ENDP
  156.  
  157. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  158. ;;; these functions are copied from emu8086.inc ;;;
  159. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  160.  
  161.  
  162. ; gets the multi-digit SIGNED number from the keyboard,
  163. ; and stores the result in CX register:
  164. SCAN_NUM PROC NEAR
  165. PUSH DX
  166. PUSH AX
  167. PUSH SI
  168.  
  169. MOV CX, 0
  170.  
  171. ; reset flag:
  172. MOV CS:make_minus, 0
  173.  
  174. next_digit:
  175.  
  176. ; get char from keyboard
  177. ; into AL:
  178. MOV AH, 00h
  179. INT 16h
  180. ; and print it:
  181. MOV AH, 0Eh
  182. INT 10h
  183.  
  184. ; check for MINUS:
  185. CMP AL, '-'
  186. JE set_minus
  187.  
  188. ; check for ENTER key:
  189. CMP AL, 0Dh ; carriage return?
  190. JNE not_cr
  191. JMP stop_input
  192. not_cr:
  193.  
  194.  
  195. CMP AL, 8 ; 'BACKSPACE' pressed?
  196. JNE backspace_checked
  197. MOV DX, 0 ; remove last digit by
  198. MOV AX, CX ; division:
  199. DIV CS:ten ; AX = DX:AX / 10 (DX-rem).
  200. MOV CX, AX
  201. PUTC ' ' ; clear position.
  202. PUTC 8 ; backspace again.
  203. JMP next_digit
  204. backspace_checked:
  205.  
  206.  
  207. ; allow only digits:
  208. CMP AL, '0'
  209. JAE ok_AE_0
  210. JMP remove_not_digit
  211. ok_AE_0:
  212. CMP AL, '9'
  213. JBE ok_digit
  214. remove_not_digit:
  215. PUTC 8 ; backspace.
  216. PUTC ' ' ; clear last entered not digit.
  217. PUTC 8 ; backspace again.
  218. JMP next_digit ; wait for next input.
  219. ok_digit:
  220.  
  221.  
  222. ; multiply CX by 10 (first time the result is zero)
  223. PUSH AX
  224. MOV AX, CX
  225. MUL CS:ten ; DX:AX = AX*10
  226. MOV CX, AX
  227. POP AX
  228.  
  229. ; check if the number is too big
  230. ; (result should be 16 bits)
  231. CMP DX, 0
  232. JNE too_big
  233.  
  234. ; convert from ASCII code:
  235. SUB AL, 30h
  236.  
  237. ; add AL to CX:
  238. MOV AH, 0
  239. MOV DX, CX ; backup, in case the result will be too big.
  240. ADD CX, AX
  241. JC too_big2 ; jump if the number is too big.
  242.  
  243. JMP next_digit
  244.  
  245. set_minus:
  246. MOV CS:make_minus, 1
  247. JMP next_digit
  248.  
  249. too_big2:
  250. MOV CX, DX ; restore the backuped value before add.
  251. MOV DX, 0 ; DX was zero before backup!
  252. too_big:
  253. MOV AX, CX
  254. DIV CS:ten ; reverse last DX:AX = AX*10, make AX = DX:AX / 10
  255. MOV CX, AX
  256. PUTC 8 ; backspace.
  257. PUTC ' ' ; clear last entered digit.
  258. PUTC 8 ; backspace again.
  259. JMP next_digit ; wait for Enter/Backspace.
  260.  
  261.  
  262. stop_input:
  263. ; check flag:
  264. CMP CS:make_minus, 0
  265. JE not_minus
  266. NEG CX
  267. not_minus:
  268.  
  269. POP SI
  270. POP AX
  271. POP DX
  272. RET
  273. make_minus DB ? ; used as a flag.
  274. SCAN_NUM ENDP
  275.  
  276. ; this procedure prints number in AX,
  277. ; used with PRINT_NUM_UNS to print signed numbers:
  278. PRINT_NUM PROC NEAR
  279. PUSH DX
  280. PUSH AX
  281.  
  282. CMP AX, 0
  283. JNZ not_zero
  284.  
  285. PUTC '0'
  286. JMP printed
  287.  
  288. not_zero:
  289. ; the check SIGN of AX,
  290. ; make absolute if it's negative:
  291. CMP AX, 0
  292. JNS positive
  293. NEG AX
  294.  
  295. PUTC '-'
  296.  
  297. positive:
  298. CALL PRINT_NUM_UNS
  299. printed:
  300. POP AX
  301. POP DX
  302. RET
  303. PRINT_NUM ENDP
  304.  
  305.  
  306.  
  307. ; this procedure prints out an unsigned
  308. ; number in AX (not just a single digit)
  309. ; allowed values are from 0 to 65535 (FFFF)
  310. PRINT_NUM_UNS PROC NEAR
  311. PUSH AX
  312. PUSH BX
  313. PUSH CX
  314. PUSH DX
  315.  
  316. ; flag to prevent printing zeros before number:
  317. MOV CX, 1
  318.  
  319. ; (result of "/ 10000" is always less or equal to 9).
  320. MOV BX, 10000 ; 2710h - divider.
  321.  
  322. ; AX is zero?
  323. CMP AX, 0
  324. JZ print_zero
  325.  
  326. begin_print:
  327.  
  328. ; check divider (if zero go to end_print):
  329. CMP BX,0
  330. JZ end_print
  331.  
  332. ; avoid printing zeros before number:
  333. CMP CX, 0
  334. JE calc
  335. ; if AX<BX then result of DIV will be zero:
  336. CMP AX, BX
  337. JB skip
  338. calc:
  339. MOV CX, 0 ; set flag.
  340.  
  341. MOV DX, 0
  342. DIV BX ; AX = DX:AX / BX (DX=remainder).
  343.  
  344. ; print last digit
  345. ; AH is always ZERO, so it's ignored
  346. ADD AL, 30h ; convert to ASCII code.
  347. PUTC AL
  348.  
  349.  
  350. MOV AX, DX ; get remainder from last div.
  351.  
  352. skip:
  353. ; calculate BX=BX/10
  354. PUSH AX
  355. MOV DX, 0
  356. MOV AX, BX
  357. DIV CS:ten ; AX = DX:AX / 10 (DX=remainder).
  358. MOV BX, AX
  359. POP AX
  360.  
  361. JMP begin_print
  362.  
  363. print_zero:
  364. PUTC '0'
  365.  
  366. end_print:
  367.  
  368. POP DX
  369. POP CX
  370. POP BX
  371. POP AX
  372. RET
  373. PRINT_NUM_UNS ENDP
  374.  
  375. GET_STRING PROC NEAR
  376. PUSH AX
  377. PUSH CX
  378. PUSH DI
  379. PUSH DX
  380.  
  381. MOV CX, 0 ; char counter.
  382.  
  383. CMP DX, 1 ; buffer too small?
  384. JBE empty_buffer ;
  385.  
  386. DEC DX ; reserve space for last zero.
  387.  
  388.  
  389. ;============================
  390. ; Eternal loop to get
  391. ; and processes key presses:
  392.  
  393. wait_for_key:
  394.  
  395. MOV AH, 0 ; get pressed key.
  396. INT 16h
  397.  
  398. CMP AL, 0Dh ; 'RETURN' pressed?
  399. JZ exit_GET_STRING
  400.  
  401.  
  402. CMP AL, 8 ; 'BACKSPACE' pressed?
  403. JNE add_to_buffer
  404. JCXZ wait_for_key ; nothing to remove!
  405. DEC CX
  406. DEC DI
  407. PUTC 8 ; backspace.
  408. PUTC ' ' ; clear position.
  409. PUTC 8 ; backspace again.
  410. JMP wait_for_key
  411.  
  412. add_to_buffer:
  413.  
  414. CMP CX, DX ; buffer is full?
  415. JAE wait_for_key ; if so wait for 'BACKSPACE' or 'RETURN'...
  416.  
  417. MOV [DI], AL
  418. INC DI
  419. INC CX
  420.  
  421. ; print the key:
  422. MOV AH, 0Eh
  423. INT 10h
  424.  
  425. JMP wait_for_key
  426. ;============================
  427.  
  428. exit_GET_STRING:
  429.  
  430. ; terminate by null:
  431. MOV DI, 0
  432.  
  433. empty_buffer:
  434.  
  435. POP DX
  436. POP DI
  437. POP CX
  438. POP AX
  439. RET
  440. GET_STRING ENDP
  441. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement