Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ; Yusufmalikul.com
- ; Kalkulator Sederhana
- ; Program ini menerima 2 input angka lalu menampilkan hasil penjumlahan, pengurangan, perkalian dan pembagian
- ; Mendukung sampai 2 digit angka
- ; Jika dilakukan pembagian dengan 0 (misal 5 dibagi 0) akan hang
- ; Belum mendukung bilangan berkoma
- ;------------------------------ Deklarasi Macro ------------------------------
- PRINT_NEWLINE MACRO ; Macro mencetak baris baru
- MOV AH, 2H ; Service untuk mencetak karakter
- MOV DL, 10 ; kode ascii karakte yg akan dicetak (10 = enter)
- INT 21H ; jalankan
- ENDM ; akhir macro
- PRINT_STRING MACRO STRING_OFFSET ; Macro untuk mencetak string
- MOV AH, 9H ; Service untuk mencetak string
- LEA DX, STRING_OFFSET ; Alamat string yang akan dicetak diletakkan di DX
- ; LEA sama dengan MOV DX, OFFSET STRING_OFFSET
- INT 21H ; Jalankan
- ENDM
- ;------------------------------ Mulai Program ------------------------------
- .MODEL SMALL
- .CODE
- ORG 100H
- ;------------------------------ Data Program ------------------------------
- DATA:
- JMP START
- INPUT1_MSG DB "Masukkan bilangan pertama : $"
- INPUT2_MSG DB "Masukkan bilangan kedua : $"
- ADD_MSG DB "Hasil penjumlahan adalah : $"
- SUB_MSG DB "Hasil pengurangan adalah : $"
- MUL_MSG DB "Hasil perkalian adalah : $"
- DIV_MSG DB "Hasil pembagian adalah : $"
- ASK_MSG DB "Ingin mengulangi (y/n)? : $"
- NUM1_SIG DB ? ; Tanda minus (sign) bilangan pertama
- NUM2_SIG DB ? ; Tanda minus (sign) bilangan kedua
- NUM1 DB ? ; Number 1. Bilangan pertama
- NUM2 DB ? ; Number 2. Bilangan kedua
- RES_SIGN DB ? ; Result Sign. Apakah hasil negatif
- OP DB ? ; Operator (+, -, *, /)
- ;------------------------------ Kode Program ------------------------------
- START:
- MOV NUM1_SIG, 0 ; Mereset semua variabel untuk melakukan perhitungan berikutnya
- MOV NUM2_SIG, 0
- MOV NUM1, 0
- MOV NUM2, 0
- PRINT_STRING INPUT1_MSG ; Cetak string dari INPUT1_MSG DB
- CALL INPUT ; Memanggil prosedur untuk mengambil input dari user
- CALL ADD_MSG_START ; Memanggil prosedur untuk menampilkan hasil
- PRINT_NEWLINE
- PRINT_NEWLINE
- PRINT_STRING ASK_MSG ; Tanyakan apakah ingin mengulangi program
- MOV AH, 1H
- INT 21H
- CMP AL, 'y'
- JE Y ; Jika input y maka ulangi program, jika n hentikan program
- JMP N
- Y:
- PRINT_NEWLINE
- PRINT_NEWLINE
- JMP START
- N:
- PRINT_NEWLINE
- INT 20H ; Akhiri jalannya program
- ADD_SUB_PROC PROC ; Proses pertambahan
- XOR AX, AX ; Untuk menampung bilangan pertama. Sama dengan MOV AX, 0
- XOR BX, BX ; Untuk menampung bilangan kedua
- XOR DX, DX ; Mencegah overflow pada pembagian
- MOV AL, [NUM1] ; Simpan bilangan pertama di AX (Karena proses pengurangan adalah AX - BX)
- MOV BL, [NUM2] ; Simpan bilangan kedua di BX
- CHECK_NUM1:
- CMP [NUM1_SIG], '-' ; Cek apakah bilangan pertama negatif
- JE NUM1_IS_NEG
- JMP CHECK_NUM2
- NUM1_IS_NEG:
- NEG AX
- CHECK_NUM2:
- CMP[NUM2_SIG], '-' ; Cek apakah bilangan kedua negatif
- JE NUM2_IS_NEG
- JMP ADD_PROCESS
- NUM2_IS_NEG:
- NEG BX ; untuk menegatifkan
- ADD_PROCESS: ; untuk pemrosesan aritmatika penambahan
- CMP [OP], '+' ; Cek apakah akan melakukan penjumlahan atau pengurangan
- JE ADD_GO
- SUB AX, BX
- JMP CHECK_RES
- ADD_GO:
- ADD AX, BX
- CHECK_RES:
- JS ADD_IS_NEG
- JMP SPLIT
- ADD_IS_NEG:
- NEG AX
- MOV [RES_SIGN], '-'
- SPLIT:
- CALL PRINT_RESULT
- RET
- ADD_SUB_PROC ENDP
- MUL_DIV_PROC PROC ; Proses pertambahan
- XOR AX, AX ; Kosongkan untuk proses pembagian
- XOR AH, AH ; Untuk mereset SF (Sign Flag) Jika tidak direset hasilnya akan negatif dan tidak sesuai
- XOR DX, DX ; Mencegah overflow pada pembagian
- MOV AL, [NUM1]
- MOV BH, [NUM2]
- MUL_CHECK_NUM1:
- CMP [NUM1_SIG], '-'
- JE MUL_NUM1_IS_NEG
- JMP MUL_CHECK_NUM2
- MUL_NUM1_IS_NEG: ; Karena belum tau akan melakukan perkalian atau pembagian
- CMP [OP], '*' ; * Berarti lakukan 2's Complement pada AL
- JE MUL_SIGN
- CMP [OP], '/'
- JE DIV_SIGN ; / Berarti lakukan 2's Complement pada AX
- DIV_SIGN:
- NEG AX
- JMP MUL_CHECK_NUM2
- MUL_SIGN:
- NEG AL
- MUL_CHECK_NUM2:
- CMP[NUM2_SIG], '-'
- JE MUL_NUM2_IS_NEG
- JMP MUL_ADD_PROCESS
- MUL_NUM2_IS_NEG:
- NEG BH
- MUL_ADD_PROCESS:
- CMP [NUM1_SIG], '-'
- JE IMUL_NEG ; Cek apakah akan melakukan perkalian bilangan positif apa negatif
- CMP [NUM2_SIG], '-'
- JE IMUL_NEG
- CMP [OP], '*' ; Cek apakah akan melakukan perkalian
- JE MUL_OP ; Jika ya maka lakukan perkalian pada bilangan positif (MUL)
- DIV BH ; AX akan dibagi dengan BH. AL = hasil bagi, AH = sisa bagi
- JMP MUL_CHECK_RES
- MUL_OP:
- MUL BH ; AX = BH * AL
- JMP MUL_CHECK_RES
- IMUL_NEG:
- CMP [OP], '*' ; Cek apakah akan melakukan perkalian
- JE IMUL_OP ; Jika ya maka lakukan perkalian pada bilangan negatif (IMUL)
- IDIV BH
- JMP MUL_CHECK_RES
- IMUL_OP:
- IMUL BH
- MUL_CHECK_RES:
- CMP [NUM1_SIG], '-'
- JE MUL_ADD_IS_NEG ; Cek apakah akan melakukan perkalian bilangan positif apa negatif
- CMP [NUM2_SIG], '-'
- JE MUL_SECOND_IS_NEG
- JMP SPLIT2
- MUL_ADD_IS_NEG:
- CMP [NUM2_SIG], '-' ; Jika bilangan kedua juga negatif maka hasilnya harus positif
- JE BOTH_NEG
- MUL_SECOND_IS_NEG:
- CMP [OP], '/'
- JE DIV_NEG
- NEG AX
- JMP RES_SIGN_DO
- DIV_NEG:
- NEG AL ; Hasil pembagian ada di AL, sehingga AL saja yang di NEG bukan AX
- RES_SIGN_DO: ; TODO
- MOV [RES_SIGN], '-' ; Untuk menandai bahwa hasilnya negatif sehingga saat dicetak keluar tanda minus (-)
- BOTH_NEG: ; Label yang akan dituju jika kedua bilangan negatif sehingga hasilnya pasti positif
- SPLIT2:
- CALL PRINT_RESULT
- RET
- MUL_DIV_PROC ENDP
- PRINT_RESULT PROC
- MOV BX, 10 ; untuk pembagi hasil agar bisa diambil digit yang terakhir 56 / 10 = 6 (sisanya) tinggal 5
- MOV CX, 0 ; Untuk mengetahui jumlah digit pada stack
- XOR DX, DX
- I: ; Menyimpan hasil penjumlahan pada stack untuk dioutputkan
- INC CX ; Tambahkan jumlah digit yang sudah disimpan di stack
- DIV BX ; Membagi DX:AX dengan BX. Hasil pembagian ada di AX, sisa pembagian ada di DX
- PUSH DX ; Simpan sisa pembagian, mulai dari satuan lalu puluhan. Simpan di stack
- XOR DX, DX ; Kosongkan untuk proses pembagian berikutnya
- CMP AX, 0 ; Cek apakah angka yang ingin dibagi sudah habis
- JNE I ; Jump If Not Equal (lompat jika AX tidak sama 0)
- MOV AH, 2H
- CMP [RES_SIGN], '-'
- JE PRINT_RES_SIGN
- JMP J
- PRINT_RES_SIGN:
- MOV DL, '-'
- INT 21H
- MOV [RES_SIGN], 0 ; Reset untuk digunakan proses lain
- J: ; Cetak isi stack
- POP DX
- ADD DL, '0' ; ditambah 30h ('0') agar bisa dicetak
- INT 21H
- LOOP J
- RET
- PRINT_RESULT ENDP
- INPUT PROC
- MOV CX, 0 ; Jumlah digit angka yang akan dimasukkan di stack (satuan atw puluhansss)
- INPUT1: ; Input angka pertama
- MOV AH, 1H ; Service untuk menerima input keyboard. Karakter yang diketikkan disimpan di AL
- INT 21H
- CMP AL, '-' ; Cek apakah ada tanda minus
- JE NEG_INPUT1 ; Jika ada maka lompat ke label NEG_INPUT1
- CMP AL, 0DH ; apakah input enter. Jika enter maka akhiri proses input
- JE INPUT1_END
- SUB AL, '0' ; Kurangkan dengan kode ascii '0' (30H) untuk mendapatkan angka
- PUSH AX ; Simpan input di stack terlebih dahulu
- INC CX ; Menambah jumlah digit yang disimpan di stack
- JMP INPUT1
- INPUT1_END: ; Jika ditekan enter maka kalikan angka pertama kemudian tambahkan ke angka kedua (misal 9 dan 5 = 9 * 10 + 5 = 95)
- MOV BL, 1 ; Masukkan pengali (10 karena desimal berbasis 10) di BL. 1 untuk mengalikan digit satuan
- INPUT1_END2:
- POP AX ; Ambil input digit terakhir
- MUL BL ; Kalikan BL dengan AL (Input digit kedua). Hasil ada di AX
- ADD [NUM1], AL ; Pindah hasil ke DL (angka maksimal adalah 99 cukup ditampung di DL)
- MOV BL, 10
- LOOP INPUT1_END2
- JMP INPUT2_MSG_START
- NEG_INPUT1:
- MOV [NUM1_SIG], '-' ; Isi NUM1_SIG dengan tanda minus '-' menandakan bahwa bilangan 1 negatif
- JMP INPUT1 ; Lakukan penginputan ulang untuk bilangan 1
- INPUT2_MSG_START:
- PRINT_STRING INPUT2_MSG ; Cetak string dari INPUT1_MSG DB
- MOV CX, 0 ; Jumlah digit angka yang akan dimasukkan
- INPUT2: ; Input angka pertama
- MOV AH, 1H ; Service untuk menerima input keyboard. Karakter yang diketikkan disimpan di AL
- INT 21H
- CMP AL, '-' ; Cek apakah ada tanda minus
- JE NEG_INPUT2 ; Jika ada maka lompat ke label NEG_INPUT1
- CMP AL, 0DH
- JE INPUT2_END
- SUB AL, '0' ; Kurangkan dengan kode ascii '0' (30H) untuk mendapatkan angka
- PUSH AX ; Simpan input di stack terlebih dahulu
- INC CX
- JMP INPUT2
- INPUT2_END: ; Jika ditekan enter maka kalikan angka pertama kemudian tambahkan ke angka kedua (misal 9 dan 5 = 9 * 10 + 5 = 95)
- MOV BL, 1 ; Masukkan pengali (10 karena desimal berbasis 10) di BL
- INPUT2_END2:
- POP AX ; Ambil input digit terakhir
- MUL BL ; Kalikan BL dengan AL (Input digit kedua). Hasil ada di AX
- ADD [NUM2], AL ; Pindah hasil ke DL (angka maksimal adalah 99 cukup ditampung di DL)
- MOV BL, 10
- LOOP INPUT2_END2
- JMP INPUT2_END3
- NEG_INPUT2:
- MOV [NUM2_SIG], '-' ; Isi NUM1_SIG dengan tanda minus '-' menandakan bahwa bilangan 1 negatif
- JMP INPUT2 ; Lakukan penginputan ulang untuk bilangan 1
- INPUT2_END3:
- RET
- INPUT ENDP
- ADD_MSG_START PROC
- PRINT_STRING ADD_MSG
- MOV [OP], '+' ; Jika ingin melakukan penjumlahan isi OP dengan simbol '+' sebelum CALL ADD_SUB_PROC
- CALL ADD_SUB_PROC
- PRINT_NEWLINE
- PRINT_STRING SUB_MSG
- MOV [OP], '-' ; Jika ingin melakukan pengurangan isi OP dengan simbol '+' sebelum CALL ADD_SUB_PROC
- CALL ADD_SUB_PROC
- PRINT_NEWLINE
- PRINT_STRING MUL_MSG
- MOV [OP], '*' ; Jika ingin melakukan perkalian isi OP dengan simbol '*' sebelum CALL MUL_DIV_PROC
- CALL MUL_DIV_PROC
- PRINT_NEWLINE
- PRINT_STRING DIV_MSG
- MOV [OP], '/' ; Jika ingin melakukan pembagian isi OP dengan simbol '/' sebelum CALL MUL_DIV_PROC
- CALL MUL_DIV_PROC
- RET
- ADD_MSG_START ENDP
- END DATA
Advertisement
Advertisement