Pembentukan Variable secara Assembly
Oleh Budhy Sutanto
Assembly listing merupakan salah satu hasil kerja program
Assembler yang sangat berguna untuk memahami teknik pemrograman Assembler,
bahasan dalam artikel ini memakai Assembly Listing untuk pemahaman pengatur
Assembler
ORG,
.DATA,
.CODE dan
DS
secara mendalam.
Tujuan akhir penulisan program assembly adalah mengisi memori-program dengan
kode-kode mesin dan data konstan, serta mengatur pemakaian memori-data. Ungkapan
di atas terdengar agak aneh, tapi memang demikianlah yang terjadi, hal ini
sering kurang disadari mereka yang baru dalam penulisan program assembly.
Letak memori yang dipakai untuk keperluan-keperluan di atas diatur oleh penulis
program assembly sepenuhnya, dengan memerhatikan perangkat keras yang dirancang,
terutama menyangkut penempatan memori dalam rangkaian yang dibuat. Penempatan
memori dalam rangkaian yang dibuat sering digambarkan dalam semacam tabel yang
dinamakan sebagai denah memori (memory map).
Origin
Untuk menentukan letak program atau data dalam memori, program Assembler
mempunyai perintah pengatur program Assembler (assembler dirictive)
yang dikenal sebagai
ORG -
singkatan dari Origin.
ORG
merupakan perintah dengan sebuah Operand yang dipakai untuk menyatakan
nomor awal memori yang akan dipakai dalam perintah baris-baris berikutnya. Nomor
memori berikutnya akan naik terus sesuai dengan pemakaian memori, sampai suatu
saat dijumpai perintah
ORG lain,
maka nomor memori yang dipakai akan berubah sesuai dengan nilai operand perintah
ORG baru.
Seperti yang diulas di atas, ada dua macam memori yang perlu di atur, yaitu
memori-program dan memori-data, jelas pengaturan kedua macam memori itu
dilakukan secara terpisah, artinya perintah
ORG yang
diberikan untuk memori-program dipakai untuk menentukan alamat memori-program,
dan nilai ini jelas berlainan dengan nilai
ORG yang
diberikan untuk memori-data.
Memori-program dan
Memori-data
Program Assembler dilengkapi pengatur program Assembler (assembler
dirictive) untuk membedakan memori yang dipakai adalah memori-program atau
memori-data, tapi perintah yang dipakai tidak seragam, artinya masing-masing
program Assembler mempunyai perintah tersendiri meskipun akhirnya bermaksud sama.
Misalkan dalam ALDS
.data (tulisan
data yang didahului dengan tanda titik) untuk menentukan baris-baris
berikutnya adalah memori-data, sedangkan untuk menentukan memori-program dipakai
perintah .code
(tulisan code yang didahului dengan tanda titik). Dalam program Assembler
lain ada yang menggantikan kedua perintah tadi dengan
dseg dan
cseg.
Dalam dunia mikrokontroler yang dimaksud dengan memori-program adalah memori
yang isinya tidak berubah meskipun sumber daya rangkaian hilang, untuk itu
biasanya dipakai memori jenis EPROM sebagai memori-program. Kini banyak dipakai
Flash PEROM sebagai memori-program, seperti dalam mikrokontroler buatan Atmel (baik
dari keluarga MCS51 maupun keluarga AVR). File program-obyek hasil kerja
program Assembler yang disimpan dalam file *.HEX, berisikan kode-kode mesin yang
nantinya diisikan ke memori-program dengan alat yang dinamakan sebagai EPROM/PEROM
Programmer. Segala susuatu yang ditulis pada bagian
.code (cseg)
akan disimpan ke dalam file *.HEX.
Sedangkan memori-data adalah memori yang isinya bisa berganti-ganti, memori-data
diberi nilai awal oleh program saat sistem mulai bekerja, dan nilai yang
disimpan di dalam memori-data akan berubah sesuai dengan keadaan kerja dari alat.
Dengan demikian dalam program-obyek tidak terdapat kode-kode untuk memori-data,
atau segala susuatu yang ditulis pada bagian
.data (dseg)
tidak akan disimpan ke dalam file *.HEX.
Pengertian Variable
Variabel merupakan suatu tempat yang diperlukan untuk menyimpan data. Saat
program bekerja sering-sering perlu menyimpan dulu beberapa nilai yang akan
dipakai lagi pada kesempatan lain.
Variabel ini bisa ditempatkan dalam register-register di dalam mikrokontroler,
sepanjang data yang harus disimpan tidak banyak dan masih ada register dalam
mikrokontroler yang belum terpakai untuk keperluan lain. Jadi pemakaian register
untuk menempatkan variabel, sangat tergantung pada jenis mikrokontroler yang
dipakai.
Mikrokontroler keluarga MCS51 mempunyai 8 register serba guna (R0..R7),
register R0
dan R1
mempunyai kegunaan lebih dibanding dengan register lainnnya, yakni kedua
register ini bisa dipakai untuk mengalamati memori-data internal, sehingga
biasanya yang dipakai sebagai penampung variable hanyalah
R2..R7
kalau memang 6 buah register tersebut tidak dipakai untuk keperluan lain. Di
samping itu masih pula ada register
B yang bisa
dipakai, karena register
B ini hanya
diperlukan untuk instruksi
MUL
AB dan
DIV
AB,
sepanjang 2 instruksi itu tidak dipakai, register
B adalah
tempat yang baik sekali untuk menampung variabel.
Mikrokontroler ciptaan Atmel yang baru, AVR, mempunyai register serba guna
sebanyak 32, meskipun beberapa register mempunyai kegunaan khusus, tapi biasanya
register sebanyak itu cukup dipakai untuk menempatkan variabel.
Memakai register-register tersebut di atas untuk tempat penyimpanan variable
tidak diperlukan cara-cara khusus, dalam penulisan program cukup diingat saja
masing-masing register dipakai untuk keperluan apa.
Kalau register-register mikrokontroler sudah tidak cukup lagi untuk menempatkan
variable, maka viariabel ditempatkan dalam memori-data. Untuk keperluan ini
diperlukan teknik-teknik penulisan program assembly.
Apa
yang ada di dalam memori-data tidak akan ditempatkan di dalam file program-obyek,
maka sesungguhnya yang dilakukan program-sumber assembly pada memori-data
hanyalah sekedar mengatur pemakaian memori-data, tidak sampai perlu
membangkitkan kode-kode. Perintah untuk pengaturan memori-data hanya satu, yakni
DS –
singkatan dari Define Storage, yakni permintaan pada program Assembler
agar mengalokasikai memori-data sebanyak sekian byte, seperti yang disebutkan
dalam operand.
Mengatur pemakaian
Memori-data
Catatan : agar pembahasan dalam artikel ini lebih mudah diterima,
Assembly Listing 1 sedikit dimodifikasi, yakni pada bagian paling kiri
diberi nomor baris (01 sampai 29), Assembly Listing yang asli tidak ada
nomor baris seperti ini.
Baris 01 pada Assembly Listing 1, berisikan perintah untuk assembler
.data,
perintah ini mengakibatkan baris-baris berikutnya sampai baris perintah
.code (baris
nomor 12) ditempatkan pada memori-data. Artinya variabel-variabel
Detik,
Menit,
Jam,
Jarak,
Kecepatan,
Penampung
berada di memori-data. Variabel-variabel tersebut tidak akan diseimpan dalam
file program obyek *.HEX.
Setelah perintah
.code baris 12 sampai baris terakhir, memori yang dipakai adalah
memori-program, apa yang terdapat dalam baris-baris ini akan disimpan sebagai
kode-kode dalam file program-obyek *.HEX.
ORG
20H pada baris 02 menyatakan baris-baris berikutnya akan ditempatkan
mulai memori nomor 20h, dengan demikian kombinasi dari baris 01 dan 02 akan
mempunyai arti baris-baris berikutnya ditempatkan di memori-data mulai nomor
20h.
Perhatikan 4 angka heksadesimal setelah nomor baris
01: dan
seterusnya. Pada baris 01 angka heksadesimal ini bernilai
0000,
maksudnya saat itu program Assembler siap pada memori nomor
0000, nomor
ini adalah nomor awal yang secara otomatis dipakai oleh program Assembler kalau
tidak diberi perintah
ORG. Pada
baris 02:
nomor memori merubah menjadi
0020, ini
sesuai dengan perintah yang diberikan pada baris
02:, yaitu
ORG 20h.
Perintah
DS
dipakai untuk mengalokasikan memori, banyaknya memori yang dialokasikan ditulis
pada bagian operand.
Baris 03 mengalokasikan 1 byte memori untuk menempatkan variable yang diberi
nama Detik
(cukup dialokasikan sebanyak 1 byte, karena nilai detik hanya akan berkisar
antara 00 sampai 59), Baris 04 mengalokasikan 1 byte memori untuk menempatkan
variable yang diberi nama
Menit dan
Baris 05 mengalokasikan 1 byte untuk
Jam.
Seperti terlihat dalam 3 baris tersebut, nama variabel (Detik,
Menit
atau Jam)
merupakan Symbol, yang namanya ditulis mulai dari huruf pertama baris
bersangkutan.
Pengertian alokasi memori ini akan menjadi jelas dengan mempelajari Assembly
secara rinci.
Variabel
Detik
ditulis pada baris 03 yakni satu baris di bawah
ORG
20h, dengan
demikian variabel
Detik ditempatkan pada memori nomor 0020h (angka 0020 setelah tulisan
03: ). Memori yang dialokasikan untuk
Detik
sebanyak 1 byte, dengan demikian memori berikutnya yang bisa dipakai adalah
memori nomor 0021h.
Hal
ini nampak jelas pada baris 04:, variabel
Menit
ditempatkan pada memori nomor 0021h (angka 0021 setelah tulisan 04:), variable
ini menempati 1 byte, sehingga variable yang ditentukan (Jam)
berikutnya ditempatkan pada memori nomor 0022h (baris 05).
Perintah
ORG 1000h
pada baris 06 mengakibatkan memori berikutnya yang akan dipakai dimulai dari
nomor 1000h, hal ini nampak variabel
Jarak pada
baris 07 ditempatkan pada memori nomor 1000h (angka 1000 setelah tulisan 07:). 2
byte dialokasikan untuk
Jarak yang
akan menempati memori nomor 1000h dan 1001h, sehingga variabel
Kecepatan
ditempatkan di nomor 1002h dan 1003h (angka 1002 setelah tulisan 08:).
Variabel
Penampung
(baris 09) dimulai dari memori nomor 1004h, dialokasikan 10h (10 heksadesimal
atau 16 desimal) untuk variabel
Penampung,
sehingga variable berikutnya (MemoriBebas
pada baris 10: ) dimulai dari memori nomor 1014h.
Untuk pemahaman yang lebih baik, bacalah secara teliti komentar-komentar yang
tertulis dalam baris-baris Assembly Listing 1.
Assembly Listing 1 - Mengatur pemakaian memori
data
01:
0000 .DATA ;
baris-2 berikut di memori-data
02:
0020 ORG 20H ;
mulai dari nomor 20h
03:
0020 Detik: DS 1 ;
alokasikan 1 byte untuk Detik
04:
0021 Menit: DS 1 ;
alokasikan 1 byte untuk Menit
05:
0022 Jam: DS 1 ;
alokasikan 1 byte untuk Jam
06:
1000 ORG 1000h ;
pindah ke memori nomor 1000h
07:
1000 Jarak: DS 2 ;
alokasikan 2 byte untuk Jarak
08:
1002 Kecepatan: DS 2 ;
alokasikan 2 byte untuk Kecepatan
09:
1004 Penampung: DS 10h ;
alokasikan 16 byte untuk Penampung
10:
1014 MemoriBebas: DS 1
11:
12:
0000 .CODE ;
baris-2 berikut di memori-program
13:
0000 ORG 0 ;
mulai dari nomor 0h
14:
0000 02 10 00 =1000 LJMP Start ;
kerjakan program di Start
15:
16:
1000 ORG 1000h ;
mulai dari nomor 1000h
17:
1000 Start:
; disini dinamakan sebagai Start
18:
1000 75 20 00 MOV Detik,#0
19:
1003 75 21 00 MOV Menit,#0
20:
1006 75 22 00 MOV Jam,#0
21:
;
22:
1009 90 10 00 MOV DPTR,#Jarak
23:
100C 7F 14 MOV R7,#MemoriBebas-Jarak
24:
100E E4 CLR A
25:
100F HapusLagi:
; dinamakan sebagai HapusLagi
26:
100F F0 MOVX @DPTR,A
27:
1010 A3 INC DPTR
28:
1011 DF FC =100F DJNZ
R7,HapusLagi ; berpindah ke HapusLagi
29:
....
Jenis-jenis Variabel
Memori-data MCS51 dibagi menjadi 2 macam, yakni memori-data internal yang
ditempatkan di dalam chip mikrokontroler yang diberi nomor 00h sampai 7Fh, dan
memori-data eksternal yang bisa ditambahkan di luar chip MCS51 yang diberi nomor
0000h sampai 0FFFFh.
Dalam penulisan program-sumber assembly, penempatan 2 jenis memori ini
tidak ada perbedaannya, hanya saja harus diingat memori-data internal nomornya
tidak boleh lebih besar dari 7Fh. Meskpun demikian pemakaian dua jenis memori-data
ini dibedakan dengan instruksi-instruksi yang berlainan.
ORG 20h
pada baris 02 dimaksud bahwa memori-data yang dipakai adalah memori-data
internal, dan
ORG
1000h pada baris 06 dimaksud bahwa memori-data yang dipakai adalah
memori-data eksternal. Baris 18; 19 dan 20 memperlihatkan contoh mengisi memori-data
internal, dan baris-barisnya berikutnya merupakan cara mengisi memori-data
eksternal.
Perintah
.CODE
pada baris 12 menyatakan bahwa perintah pada baris-baris berikutnya ditempatkan
pada memori-program yang dimulai pada memori nomor 0000h (baris 13 –
ORG 0).
Perintah pada baris 14 adalah
LJMP Start,
yakni hanya bermaksud mengalihkan program yang harus dikerjakan pada
Start: yang
berada di memori-program nomor 1000h karena perintah
ORG 1000h
pada baris 1000h.
Instruksi
MOV
merupakan perintah yang dipakai mengisi memori-data internal. Pengisian ini bisa
dilakukan secara langsung dengan cara menyebut nama memori yang dikehendaki (dalam
hal ini adalah
Detik,
Menit dan
Jam), nilai
yang diisikan ke memori-data internal tersebut adalah bilangan konstan 0 (dituliskan
sebagai #0).
Pengisian memori-data eksternal, hanya bisa dilakukan dengan bantuan
DPTR, yakni
memakai instruksi
MOVX @DPTR,A.
Untuk memakai instruksi ini sebelumnya
DPTR harus
diisi dengan nomor memori-data eksternal yang dimaksud, baris 22:
MOV DPTR,#Jarak.
Seperti terlihat pada baris 07, variabel
Jarak
menempatan memori nomor 1000h (angka 1000 setelah tulisan 07: ), pada baris 22:
nomor memori 1000h ini diisikan ke
DPTR (22:
1009 90 10 00, kode-kode ini bisa diartikan dengan : 90 artinya isilah
DPTR dengan
bilangan 2 byte berikutnya, yakni bilangan 10 00 yang artinya 1000h)
Potongan program pada baris 22 sampai 28 bermaksud mengisi variable
Jarak,
Kecepatan
dan Penampung,
3 variable ini menempati memori sebagai 14h byte, banyaknya memori ini bisa
dihitung dengan bantuan assembler seperti terlihat pada baris 23:
MOV
R7,#MemoriBebas-Jarak.
Dalam hal operand berupa sebuah persamaan, maka Assembler akan menghitung dulu
nilai persamaan ini dan hasilnya yang dijadikan program-obyek Dalam hal nilai
MemoriBebas
adalah 1014h (angka 1014 di belakang nomor baris 10: ), nilai
Jarak
adalah 1000h (angka 1000 di belakang nomor baris 7: ), hasil pengurangan 2
nilai tadi sebesar 14h dan dijadikan program-obyek dalam baris
23: 100C
7F 14 (kode-kode
ini bisa diartikan dengan :
7F artinya
isilah R7
dengan bilangan 1 byte berikutnya, yakni bilangan 14 yang merupakan hasil
perhitungan operand di atas)