Advertisement
Yusufmm

Kalkulator Sederhana (TASM)

Jun 30th, 2016
122
0
Never
1
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.81 KB | None | 0 0
  1. ; Yusufmalikul.com
  2. ; Kalkulator Sederhana
  3. ; Program ini menerima 2 input angka lalu menampilkan hasil penjumlahan, pengurangan, perkalian dan pembagian
  4. ; Mendukung sampai 2 digit angka
  5. ; Jika dilakukan pembagian dengan 0 (misal 5 dibagi 0) akan hang
  6. ; Belum mendukung bilangan berkoma
  7.  
  8. ;------------------------------ Deklarasi Macro ------------------------------
  9. PRINT_NEWLINE MACRO ; Macro mencetak baris baru
  10. MOV AH, 2H ; Service untuk mencetak karakter
  11. MOV DL, 10 ; kode ascii karakte yg akan dicetak (10 = enter)
  12. INT 21H ; jalankan
  13. ENDM ; akhir macro
  14.  
  15. PRINT_STRING MACRO STRING_OFFSET ; Macro untuk mencetak string
  16. MOV AH, 9H ; Service untuk mencetak string
  17. LEA DX, STRING_OFFSET ; Alamat string yang akan dicetak diletakkan di DX
  18. ; LEA sama dengan MOV DX, OFFSET STRING_OFFSET
  19. INT 21H ; Jalankan
  20. ENDM
  21.  
  22. ;------------------------------ Mulai Program ------------------------------
  23. .MODEL SMALL
  24. .CODE
  25. ORG 100H
  26. ;------------------------------ Data Program ------------------------------
  27. DATA:
  28. JMP START
  29. INPUT1_MSG DB "Masukkan bilangan pertama : $"
  30. INPUT2_MSG DB "Masukkan bilangan kedua : $"
  31. ADD_MSG DB "Hasil penjumlahan adalah : $"
  32. SUB_MSG DB "Hasil pengurangan adalah : $"
  33. MUL_MSG DB "Hasil perkalian adalah : $"
  34. DIV_MSG DB "Hasil pembagian adalah : $"
  35. ASK_MSG DB "Ingin mengulangi (y/n)? : $"
  36. NUM1_SIG DB ? ; Tanda minus (sign) bilangan pertama
  37. NUM2_SIG DB ? ; Tanda minus (sign) bilangan kedua
  38. NUM1 DB ? ; Number 1. Bilangan pertama
  39. NUM2 DB ? ; Number 2. Bilangan kedua
  40. RES_SIGN DB ? ; Result Sign. Apakah hasil negatif
  41. OP DB ? ; Operator (+, -, *, /)
  42.  
  43. ;------------------------------ Kode Program ------------------------------
  44. START:
  45.  
  46. MOV NUM1_SIG, 0 ; Mereset semua variabel untuk melakukan perhitungan berikutnya
  47. MOV NUM2_SIG, 0
  48. MOV NUM1, 0
  49. MOV NUM2, 0
  50.  
  51. PRINT_STRING INPUT1_MSG ; Cetak string dari INPUT1_MSG DB
  52.  
  53. CALL INPUT ; Memanggil prosedur untuk mengambil input dari user
  54.  
  55. CALL ADD_MSG_START ; Memanggil prosedur untuk menampilkan hasil
  56.  
  57. PRINT_NEWLINE
  58. PRINT_NEWLINE
  59.  
  60. PRINT_STRING ASK_MSG ; Tanyakan apakah ingin mengulangi program
  61.  
  62. MOV AH, 1H
  63. INT 21H
  64. CMP AL, 'y'
  65. JE Y ; Jika input y maka ulangi program, jika n hentikan program
  66. JMP N
  67. Y:
  68. PRINT_NEWLINE
  69. PRINT_NEWLINE
  70.  
  71. JMP START
  72. N:
  73. PRINT_NEWLINE
  74.  
  75. INT 20H ; Akhiri jalannya program
  76.  
  77. ADD_SUB_PROC PROC ; Proses pertambahan
  78. XOR AX, AX ; Untuk menampung bilangan pertama. Sama dengan MOV AX, 0
  79. XOR BX, BX ; Untuk menampung bilangan kedua
  80. XOR DX, DX ; Mencegah overflow pada pembagian
  81. MOV AL, [NUM1] ; Simpan bilangan pertama di AX (Karena proses pengurangan adalah AX - BX)
  82. MOV BL, [NUM2] ; Simpan bilangan kedua di BX
  83.  
  84. CHECK_NUM1:
  85. CMP [NUM1_SIG], '-' ; Cek apakah bilangan pertama negatif
  86. JE NUM1_IS_NEG
  87. JMP CHECK_NUM2
  88. NUM1_IS_NEG:
  89. NEG AX
  90. CHECK_NUM2:
  91. CMP[NUM2_SIG], '-' ; Cek apakah bilangan kedua negatif
  92. JE NUM2_IS_NEG
  93. JMP ADD_PROCESS
  94. NUM2_IS_NEG:
  95. NEG BX ; untuk menegatifkan
  96. ADD_PROCESS: ; untuk pemrosesan aritmatika penambahan
  97. CMP [OP], '+' ; Cek apakah akan melakukan penjumlahan atau pengurangan
  98. JE ADD_GO
  99. SUB AX, BX
  100. JMP CHECK_RES
  101. ADD_GO:
  102. ADD AX, BX
  103. CHECK_RES:
  104. JS ADD_IS_NEG
  105. JMP SPLIT
  106. ADD_IS_NEG:
  107. NEG AX
  108. MOV [RES_SIGN], '-'
  109. SPLIT:
  110. CALL PRINT_RESULT
  111. RET
  112. ADD_SUB_PROC ENDP
  113.  
  114. MUL_DIV_PROC PROC ; Proses pertambahan
  115. XOR AX, AX ; Kosongkan untuk proses pembagian
  116. XOR AH, AH ; Untuk mereset SF (Sign Flag) Jika tidak direset hasilnya akan negatif dan tidak sesuai
  117. XOR DX, DX ; Mencegah overflow pada pembagian
  118. MOV AL, [NUM1]
  119. MOV BH, [NUM2]
  120.  
  121. MUL_CHECK_NUM1:
  122. CMP [NUM1_SIG], '-'
  123. JE MUL_NUM1_IS_NEG
  124. JMP MUL_CHECK_NUM2
  125. MUL_NUM1_IS_NEG: ; Karena belum tau akan melakukan perkalian atau pembagian
  126. CMP [OP], '*' ; * Berarti lakukan 2's Complement pada AL
  127. JE MUL_SIGN
  128. CMP [OP], '/'
  129. JE DIV_SIGN ; / Berarti lakukan 2's Complement pada AX
  130. DIV_SIGN:
  131. NEG AX
  132. JMP MUL_CHECK_NUM2
  133. MUL_SIGN:
  134. NEG AL
  135. MUL_CHECK_NUM2:
  136. CMP[NUM2_SIG], '-'
  137. JE MUL_NUM2_IS_NEG
  138. JMP MUL_ADD_PROCESS
  139. MUL_NUM2_IS_NEG:
  140. NEG BH
  141. MUL_ADD_PROCESS:
  142. CMP [NUM1_SIG], '-'
  143. JE IMUL_NEG ; Cek apakah akan melakukan perkalian bilangan positif apa negatif
  144. CMP [NUM2_SIG], '-'
  145. JE IMUL_NEG
  146. CMP [OP], '*' ; Cek apakah akan melakukan perkalian
  147. JE MUL_OP ; Jika ya maka lakukan perkalian pada bilangan positif (MUL)
  148. DIV BH ; AX akan dibagi dengan BH. AL = hasil bagi, AH = sisa bagi
  149. JMP MUL_CHECK_RES
  150. MUL_OP:
  151. MUL BH ; AX = BH * AL
  152. JMP MUL_CHECK_RES
  153. IMUL_NEG:
  154. CMP [OP], '*' ; Cek apakah akan melakukan perkalian
  155. JE IMUL_OP ; Jika ya maka lakukan perkalian pada bilangan negatif (IMUL)
  156. IDIV BH
  157. JMP MUL_CHECK_RES
  158. IMUL_OP:
  159. IMUL BH
  160. MUL_CHECK_RES:
  161. CMP [NUM1_SIG], '-'
  162. JE MUL_ADD_IS_NEG ; Cek apakah akan melakukan perkalian bilangan positif apa negatif
  163. CMP [NUM2_SIG], '-'
  164. JE MUL_SECOND_IS_NEG
  165. JMP SPLIT2
  166. MUL_ADD_IS_NEG:
  167. CMP [NUM2_SIG], '-' ; Jika bilangan kedua juga negatif maka hasilnya harus positif
  168. JE BOTH_NEG
  169. MUL_SECOND_IS_NEG:
  170. CMP [OP], '/'
  171. JE DIV_NEG
  172. NEG AX
  173. JMP RES_SIGN_DO
  174. DIV_NEG:
  175. NEG AL ; Hasil pembagian ada di AL, sehingga AL saja yang di NEG bukan AX
  176. RES_SIGN_DO: ; TODO
  177. MOV [RES_SIGN], '-' ; Untuk menandai bahwa hasilnya negatif sehingga saat dicetak keluar tanda minus (-)
  178. BOTH_NEG: ; Label yang akan dituju jika kedua bilangan negatif sehingga hasilnya pasti positif
  179. SPLIT2:
  180. CALL PRINT_RESULT
  181. RET
  182. MUL_DIV_PROC ENDP
  183.  
  184. PRINT_RESULT PROC
  185. MOV BX, 10 ; untuk pembagi hasil agar bisa diambil digit yang terakhir 56 / 10 = 6 (sisanya) tinggal 5
  186. MOV CX, 0 ; Untuk mengetahui jumlah digit pada stack
  187. XOR DX, DX
  188.  
  189. I: ; Menyimpan hasil penjumlahan pada stack untuk dioutputkan
  190. INC CX ; Tambahkan jumlah digit yang sudah disimpan di stack
  191. DIV BX ; Membagi DX:AX dengan BX. Hasil pembagian ada di AX, sisa pembagian ada di DX
  192.  
  193. PUSH DX ; Simpan sisa pembagian, mulai dari satuan lalu puluhan. Simpan di stack
  194. XOR DX, DX ; Kosongkan untuk proses pembagian berikutnya
  195. CMP AX, 0 ; Cek apakah angka yang ingin dibagi sudah habis
  196. JNE I ; Jump If Not Equal (lompat jika AX tidak sama 0)
  197.  
  198. MOV AH, 2H
  199. CMP [RES_SIGN], '-'
  200. JE PRINT_RES_SIGN
  201. JMP J
  202. PRINT_RES_SIGN:
  203. MOV DL, '-'
  204. INT 21H
  205. MOV [RES_SIGN], 0 ; Reset untuk digunakan proses lain
  206.  
  207. J: ; Cetak isi stack
  208. POP DX
  209. ADD DL, '0' ; ditambah 30h ('0') agar bisa dicetak
  210. INT 21H
  211. LOOP J
  212. RET
  213. PRINT_RESULT ENDP
  214.  
  215. INPUT PROC
  216. MOV CX, 0 ; Jumlah digit angka yang akan dimasukkan di stack (satuan atw puluhansss)
  217. INPUT1: ; Input angka pertama
  218. MOV AH, 1H ; Service untuk menerima input keyboard. Karakter yang diketikkan disimpan di AL
  219. INT 21H
  220. CMP AL, '-' ; Cek apakah ada tanda minus
  221. JE NEG_INPUT1 ; Jika ada maka lompat ke label NEG_INPUT1
  222. CMP AL, 0DH ; apakah input enter. Jika enter maka akhiri proses input
  223. JE INPUT1_END
  224. SUB AL, '0' ; Kurangkan dengan kode ascii '0' (30H) untuk mendapatkan angka
  225. PUSH AX ; Simpan input di stack terlebih dahulu
  226. INC CX ; Menambah jumlah digit yang disimpan di stack
  227. JMP INPUT1
  228. INPUT1_END: ; Jika ditekan enter maka kalikan angka pertama kemudian tambahkan ke angka kedua (misal 9 dan 5 = 9 * 10 + 5 = 95)
  229. MOV BL, 1 ; Masukkan pengali (10 karena desimal berbasis 10) di BL. 1 untuk mengalikan digit satuan
  230. INPUT1_END2:
  231. POP AX ; Ambil input digit terakhir
  232. MUL BL ; Kalikan BL dengan AL (Input digit kedua). Hasil ada di AX
  233. ADD [NUM1], AL ; Pindah hasil ke DL (angka maksimal adalah 99 cukup ditampung di DL)
  234.  
  235. MOV BL, 10
  236. LOOP INPUT1_END2
  237. JMP INPUT2_MSG_START
  238.  
  239. NEG_INPUT1:
  240. MOV [NUM1_SIG], '-' ; Isi NUM1_SIG dengan tanda minus '-' menandakan bahwa bilangan 1 negatif
  241. JMP INPUT1 ; Lakukan penginputan ulang untuk bilangan 1
  242.  
  243. INPUT2_MSG_START:
  244.  
  245. PRINT_STRING INPUT2_MSG ; Cetak string dari INPUT1_MSG DB
  246.  
  247. MOV CX, 0 ; Jumlah digit angka yang akan dimasukkan
  248. INPUT2: ; Input angka pertama
  249. MOV AH, 1H ; Service untuk menerima input keyboard. Karakter yang diketikkan disimpan di AL
  250. INT 21H
  251. CMP AL, '-' ; Cek apakah ada tanda minus
  252. JE NEG_INPUT2 ; Jika ada maka lompat ke label NEG_INPUT1
  253. CMP AL, 0DH
  254. JE INPUT2_END
  255. SUB AL, '0' ; Kurangkan dengan kode ascii '0' (30H) untuk mendapatkan angka
  256. PUSH AX ; Simpan input di stack terlebih dahulu
  257. INC CX
  258. JMP INPUT2
  259. INPUT2_END: ; Jika ditekan enter maka kalikan angka pertama kemudian tambahkan ke angka kedua (misal 9 dan 5 = 9 * 10 + 5 = 95)
  260. MOV BL, 1 ; Masukkan pengali (10 karena desimal berbasis 10) di BL
  261. INPUT2_END2:
  262. POP AX ; Ambil input digit terakhir
  263. MUL BL ; Kalikan BL dengan AL (Input digit kedua). Hasil ada di AX
  264. ADD [NUM2], AL ; Pindah hasil ke DL (angka maksimal adalah 99 cukup ditampung di DL)
  265.  
  266. MOV BL, 10
  267. LOOP INPUT2_END2
  268. JMP INPUT2_END3
  269.  
  270. NEG_INPUT2:
  271. MOV [NUM2_SIG], '-' ; Isi NUM1_SIG dengan tanda minus '-' menandakan bahwa bilangan 1 negatif
  272. JMP INPUT2 ; Lakukan penginputan ulang untuk bilangan 1
  273. INPUT2_END3:
  274. RET
  275. INPUT ENDP
  276.  
  277. ADD_MSG_START PROC
  278.  
  279. PRINT_STRING ADD_MSG
  280.  
  281. MOV [OP], '+' ; Jika ingin melakukan penjumlahan isi OP dengan simbol '+' sebelum CALL ADD_SUB_PROC
  282. CALL ADD_SUB_PROC
  283.  
  284. PRINT_NEWLINE
  285.  
  286. PRINT_STRING SUB_MSG
  287.  
  288. MOV [OP], '-' ; Jika ingin melakukan pengurangan isi OP dengan simbol '+' sebelum CALL ADD_SUB_PROC
  289. CALL ADD_SUB_PROC
  290.  
  291. PRINT_NEWLINE
  292.  
  293. PRINT_STRING MUL_MSG
  294.  
  295. MOV [OP], '*' ; Jika ingin melakukan perkalian isi OP dengan simbol '*' sebelum CALL MUL_DIV_PROC
  296. CALL MUL_DIV_PROC
  297.  
  298. PRINT_NEWLINE
  299.  
  300. PRINT_STRING DIV_MSG
  301.  
  302. MOV [OP], '/' ; Jika ingin melakukan pembagian isi OP dengan simbol '/' sebelum CALL MUL_DIV_PROC
  303. CALL MUL_DIV_PROC
  304. RET
  305. ADD_MSG_START ENDP
  306.  
  307. END DATA
Advertisement
Comments
Add Comment
Please, Sign In to add comment
Advertisement