Kali ini kita coba ulas kembali tentang bahasa pemrograman yang jarang sekali dipakai oleh para programmer, biasanya kita mempelajari pemrograman java, php, c++ dll, kini kita coba pemrograman dibidang bahasa rakitan, pemrograman bahasa assembly.banyak sekali contoh program bahasa assembly, disini saya akan mencontohkan tentang program sederhana yaitu program kalkulator. program ini berjalan menggunakan emulator emu8086, bagi kalian yang belum punya programnya silahkan download gratis.
Sebelum kalian mencoba aplikasinya, sebaiknya kalian pelajari juga dasar- dasar dari pemrograman bahasa assembly, agar kalian bisa memahami setiap baris dalam source kode programnya nanti.
Untuk artikel bahasa assembly bisa kalian download disini
Kode Program Dan Penjelasan Setiap Baris Program
Berikut merupakan kode
program kalkulator sederhana menggunakan bahasa assembly:
name "calc2"
org 100h
jmp start
; definisi
variabel:
msg0 db "PROGRAM KALKULATOR DEDE RUBIANTO 1003040022 ",0Dh,0Ah
db " MASUKAN KODE BERIKUT : *,/,+,- TEKAN enter UNTUK MENJALANKAN
PROGRAM",0Dh,0Ah,'$'
msg1 db 0Dh,0Ah, 0Dh,0Ah, 'MASUKAN ANGKA: $'
msg2 db "MASUKAN KODE:
+ - *
/ : $"
msg3 db "MASUKAN ANGKA KEDUA: $"
msg4 db 0dh,0ah , 'HASIL :
$'
msg5 db 0dh,0ah ,'TERIMA
KASIH MENGGUNAKAN KALKULATOR ,SEMOGA BERMANFAAT BAGI ANDA!', 0Dh,0Ah, '$'
err1 db "kode yang dimasukan tidak cocok!", 0Dh,0Ah , '$'
smth db " TIDAK ADA
HASIL.... $"
; operator
perhitungan dapat berupa: '+','-','*','/' atau 'q' untuk keluar.
opr db '?'
; no
pertama dan kedua:
num1 dw ?
num2 dw ?
mulai:
mov dx, offset msg0
mov ah, 9
int 21h
lea dx, msg1
mov ah, 09h ; keluaran string di ds:dx
int 21h
call scan_num
; store first number:
mov num1, cx
; baris
baru:
putc 0Dh
putc 0Ah
lea dx, msg2
mov ah, 09h ; keluaran string di ds:dx
int 21h
; pilih
operator perhitungan:
mov ah, 1 ; single char
input to AL.
int 21h
mov opr, al
; baris
baru:
putc 0Dh
putc 0Ah
cmp opr, 'q' ; q – untuk keluar.
je exit
cmp opr, '*'
jb wrong_opr
cmp opr, '/'
ja wrong_opr
; keluaran
berupa string di ds:dx
lea dx, msg3
mov ah, 09h
int 21h
call scan_num
; penyimpanan
no kedua
mov num2, cx
lea dx, msg4
mov ah, 09h ; keluaran string di ds:dx
int 21h
; perhitungan:
cmp opr, '+'
je do_plus
cmp opr, '-'
je do_minus
cmp opr, '*'
je do_mult
cmp opr, '/'
je do_div
; apabila
input kosong....
wrong_opr:
lea dx, err1
mov ah, 09h ; output
string at ds:dx
int 21h
keluar:
; output of a string at ds:dx
lea dx, msg5
mov ah, 09h
int 21h
; tekan
sembarang tombol...
mov ah, 0
int 16h
ret ; kembali .
do_plus:
mov ax, num1
add ax, num2
call print_num ; print ax
value.
jmp exit
do_minus:
mov ax, num1
sub ax, num2
call print_num ; print ax
value.
jmp exit
do_mult:
mov ax, num1
imul num2 ; (dx ax) = ax * num2.
call print_num ; print ax
value.
; dx is ignored (calc works with tiny numbers only).
jmp exit
do_div:
; dx is ignored (calc works with tiny integer numbers only).
mov dx, 0
mov ax, num1
idiv num2 ; ax = (dx ax) /
num2.
cmp dx, 0
jnz approx
call print_num ; print ax
value.
jmp exit
approx:
call print_num ; print ax
value.
lea dx, smth
mov ah, 09h ; output
string at ds:dx
int 21h
jmp exit
SCAN_NUM PROC NEAR
PUSH DX
PUSH
AX
PUSH SI
MOV CX, 0
; reset flag:
MOV CS:make_minus, 0
next_digit:
; get char from
keyboard
; into AL:
MOV AH, 00h
INT 16h
; and print it:
MOV
AH, 0Eh
INT 10h
; check for MINUS:
CMP AL, '-'
JE set_minus
; check for ENTER
key:
CMP AL, 0Dh
; carriage return?
JNE not_cr
JMP stop_input
not_cr:
CMP AL, 8 ; 'BACKSPACE' pressed?
JNE backspace_checked
MOV DX, 0 ; remove last digit by
MOV AX, CX ; division:
DIV CS:ten ; AX = DX:AX / 10 (DX-rem).
MOV CX, AX
PUTC ' ' ; clear position.
PUTC 8 ; backspace again.
JMP next_digit
backspace_checked:
; allow only digits:
CMP AL, '0'
JAE ok_AE_0
JMP remove_not_digit
ok_AE_0:
CMP AL, '9'
JBE ok_digit
remove_not_digit:
PUTC 8
; backspace.
PUTC ' '
; clear last entered not digit.
PUTC
8 ; backspace again.
JMP next_digit ; wait for next input.
ok_digit:
; multiply CX by 10
(first time the result is zero)
PUSH AX
MOV AX, CX
MUL CS:ten ; DX:AX = AX*10
MOV CX, AX
POP AX
; mengecek input yang terlalu besar
; (result should be
16 bits)
CMP DX, 0
JNE too_big
; convert from ASCII
code:
SUB AL, 30h
; add AL to CX:
MOV AH, 0
MOV DX, CX
; backup, in case the result will be too big.
ADD CX, AX
JC too_big2 ; jump if the number is too big.
JMP next_digit
set_minus:
MOV CS:make_minus, 1
JMP next_digit
too_big2:
MOV CX, DX
; restore the backuped value before add.
MOV DX, 0
; DX was zero before backup!
too_big:
MOV AX, CX
DIV CS:ten
; reverse last DX:AX = AX*10, make AX = DX:AX / 10
MOV CX, AX
PUTC 8
; backspace.
PUTC ' '
; clear last entered digit.
PUTC 8
; backspace again.
JMP next_digit ; wait for Enter/Backspace.
stop_input:
; check flag:
CMP CS:make_minus, 0
JE not_minus
NEG CX
not_minus:
POP SI
POP AX
POP DX
RET
make_minus DB ?
; used as a flag.
SCAN_NUM ENDP
; this procedure prints number in AX,
; used with PRINT_NUM_UNS to print signed numbers:
PRINT_NUM PROC NEAR
PUSH DX
PUSH AX
CMP AX, 0
JNZ not_zero
PUTC '0'
JMP printed
not_zero:
; the check SIGN of
AX,
; make absolute if
it's negative:
CMP AX, 0
JNS positive
NEG AX
PUTC '-'
positive:
CALL PRINT_NUM_UNS
printed:
POP AX
POP DX
RET
PRINT_NUM ENDP
; number in AX (not just a single digit)
; allowed values are from 0 to 65535 (FFFF)
PRINT_NUM_UNS PROC NEAR
PUSH AX
PUSH BX
PUSH CX
PUSH DX
; flag to prevent
printing zeros before number:
MOV CX, 1
; (result of "/
10000" is always less or equal to 9).
MOV BX, 10000 ; 2710h - divider.
; AX is zero?
CMP AX, 0
JZ print_zero
begin_print:
; check divider (if zero go to
end_print):
CMP BX,0
JZ end_print
; avoid printing
zeros before number:
CMP CX, 0
JE calc
; if AX<BX then
result of DIV will be zero:
CMP AX, BX
JB skip
calc:
MOV CX, 0
; set flag.
MOV DX, 0
DIV BX
; AX = DX:AX / BX
(DX=remainder).
; print last digit
; AH is always ZERO,
so it's ignored
ADD AL, 30h
; convert to ASCII code.
PUTC AL
MOV AX, DX
; get remainder from last div.
skip:
; calculate BX=BX/10
PUSH AX
MOV DX, 0
MOV AX, BX
DIV CS:ten
; AX = DX:AX / 10
(DX=remainder).
MOV
BX, AX
POP AX
JMP begin_print
print_zero:
PUTC '0'
end_print:
POP DX
POP CX
POP BX
POP AX
RET
PRINT_NUM_UNS ENDP
ten DW
10 ; used as
multiplier/divider by SCAN_NUM & PRINT_NUM_UNS.
GET_STRING PROC NEAR
PUSH AX
PUSH CX
PUSH DI
PUSH DX
MOV CX, 0 ; char counter.
CMP DX, 1 ; buffer too small?
JBE empty_buffer ;
DEC DX ; reserve space for last
zero.
;============================
; Eternal loop to get
; and processes key presses:
wait_for_key:
MOV AH, 0 ; get pressed key.
INT 16h
CMP AL, 0Dh ; 'RETURN' pressed?
JZ exit_GET_STRING
CMP AL, 8 ; 'BACKSPACE' pressed?
JNE add_to_buffer
JCXZ wait_for_key ; nothing to remove!
DEC CX
DEC DI
PUTC 8 ; backspace.
PUTC ' ' ; clear position.
PUTC 8 ; backspace again.
JMP wait_for_key
add_to_buffer:
CMP CX, DX ; buffer is full?
JAE wait_for_key ; if so wait for 'BACKSPACE' or 'RETURN'...
MOV [DI], AL
INC DI
INC CX
; print the key:
MOV AH, 0Eh
INT 10h
JMP wait_for_key
;============================
exit_GET_STRING:
; terminate by null:
MOV [DI], 0
empty_buffer:
POP DX
POP DI
POP CX
POP AX
RET
GET_STRING ENDP
Untuk output dari source kode diatas seperti dibawah ini :
Semoga artikel ini bisa bermanfaat gays, bila ada kesalahan atau kurang jelas silahkan coret - coret dikolom koment . Salam Wong Tani. . . . .
Tidak ada komentar:
Posting Komentar