Anda di halaman 1dari 57

PETUNJUK EKSPERIMEN

MIKROKOMPUTER
Program Studi S1 ELINS

Unit Layanan Elektronika dan Unit Layanan Instrumentasi


Jurusan Ilmu Komputer dan Elektronika
Fakultas Matematika dan Ilmu Pengetahuan Alama
Universitas Gadjah Mada
Yogyakarta
2

DAFTAR ISI

SISTEM BILANGAN ............................................................................................................................ 3

BAHASA ASSEMBLY ......................................................................................................................... 11

MODUL I

AKSES MEMORY .............................................................................................................................. 15

MODUL II

VARIABEL ........................................................................................................................................ 19

MODUL III

INTERUPSI ....................................................................................................................................... 27

MODUL IV

LIBRARY OF COMMON FUNCTION................................................................................................... 29

MODUL V

INSTRUKSI ARITMATIKA DAN LOGIKA ............................................................................................. 33

MODUL VI

ALIRAN KENDALI PROGRAM ........................................................................................................... 37

MODUL VII

PROSEDUR ...................................................................................................................................... 45

MODUL VIII

STACK.............................................................................................................................................. 48

MODUL IX

MAKRO ........................................................................................................................................... 51

MODUL X

PENGENDALIAN PIRANTI EKSTERNAL .............................................................................................. 54


3

Sistem Bilangan
1. Sistem Desimal

Umumnya kebanyakan orang menggunakan representasikan nilai decimal


untuk melakukan operasi perhitungan. Dalam sistem decimal dikenal 10 digit
bilangan:

0, 1, 2, 3, 4, 5, 6, 7, 8, 9

Digit-digit tersebut dapat merepresentasikan nilai berapa saja, misalnya: 754.


Nilai dibentuk dari jumlah setiap digit, kemudian dikalikan dengan pangkat base
sesuai posisi digit, sepereti contoh ilustrasi dibawah (dalam kasus ini basisnya adalah
10 karena ada 10 digit dalam sistem desimal.

Posisi masing-masing digit sangat penting, misalnya bila kita tempatkan angka
7 pada akhir digit: 547, maka akan terbentuk nilai yang lain dari sebelumnya, seperti
terliha pada ilustrasi berikut.

Catatan penting : tiap angka dalam pangkat nol hasilnya 1, bahkan nol pangkat nol
hasilnya juga 1.
4

2. Sistem Biner

Komputer tidaklah secerdas manusia (atau belum secerdas itu), maka akan
lebih mudah untuk membuat mesin elektronik dengan dua keadaan (state) : on and
off, atau 1 dan 0. Komputer menggunakan sistem biner. Yaitu sistem dengan 2 digit:
0, 1. Maka dengan demikian base-nya adalah 2. Setiap angka digit dalam sistem
biner disebut BIT, setiap 4 bit disebut Nibble, setiap 8 bit disebut Byte, bentuk 2 byte
disebut Word, dan bentuk 2 word disebut Double Word.

Ada duatu aturan untuk menambahkan b pada setiap akhir angka binner,
sehingga dengan cara ini kita dapat mengetahui bahwa 101b adalah angka biner
dengan nilai decimal 5. Sedangkan bila diberikan angka biner 10100101b makan
dapat dikonversi menjadi nilai decimal 165.

3. Sistem Heksadesimal

Sistem heksadesimal menggunakan 16 digit

0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F

Sehingga dengan demikian basenya adalah 16. Angka heksadesimal lebih sederhana
dan mudah untuk dibaca, serta lebih mudah untuk mengkonversi angka dari sistem
5

biner ke sistem heksadesimal dan sebaliknya, dimana setiap nibble 94 bit) dapat
dikonversi ke digit heksadesimal berdasarkan table berikut.

Terdapat suatu aturan untuk menambahkan “h” disetiap akhir angka heksadesimal,
dengan cara ini dapat diketahui bahwa 5Fh adalah angka heksadesimal dengan nilai
decimal 95. Penambahan “0” (nol) juga diperlukan pada awal angka heksadesimal
yang dimulai dengan huruf (A..F), misalnya 0E120h. Konversi angka heksadesimal
1234h (atau sama dengan nilai decimal 4660) diilustrasikan sebagai berikut.
6

Konversi Sistem Desimal ke Sistem Lainnya

Untuk mengkonversi dari sistem decimal ke sistem yang lain , maka diperlukan
pembagian nilai decimal dengan base dari system yang diingingkan, dan setiap
melakukan operasi pembagian perlu diingatkan nilai hasi bagi (result) dan
menyimpan sisa hasil bagi (remainder), dan proses pembagian ini dilakukan hingga
hasilnya adalah 0, Sisa hasil bagi kemudian digunakan untuk mewakili nilai dalam
sistem. Ilustrasi perubahan nilai dari 39 (base 10) ke sistem heksadesimal (base 16)
digambarkan sebagai berikut.

Seperti yang terlihat pada ilustrasi diatas, didapatkan angka heksdadesimal: 27h.
semua sisa hasil bagi (remainder) berada dibawah angka 10, sehingga dalam kasus
konversi ini tidak menggunakan symbol huruf. Contoh lainnya, mengubah 43868
kebentuk heksadesimal, sebagai berikut.
7

Hasilnya adalah OAB5C, dengan merujuk table konversi yang telah dijelaskan
seblumnya untuk mengubah sisa hasil bagi yang lebih dari 9 ke symbol huruf yang
sesuai. Dengan menggunakan prinsip yang sama, kita dapat mengubah bentuk biner
(menggunakan bilangan 2 sebagai pembagi), atau mengubah ke angka
heksadesimal, dan kemudian mengubahnya ke angka biner menggunakan table
konversi.

Maka didapatlah anga biner 1010 1011 0101 1100

Bilangan Bertanda

Tidak ada cara yang meyakinkan apakah byte heksadesimal 0FFh adalah
posistif atau negatif, yang dapat direpresentasikan dengan nilai decimal 255 dan -1.
8 bit dapat digunakan untuk membuat kombinasi sebanyal 256 (termasul nol),
8

sehingga kita dapat dengan mudah menduga bahwa kombinasi 128 pertama (0..127)
akan merepresentasikan bilangan posistif dan kombinasi 128 kemudian (128..255)
akan merepresentasikan bilangan negatif. Bila inign mendapatkan nilai “-5”, kita
harus mengurangi 5 dari kombinasi angka (256), sehingga didapatka 256-5 = 251.

Menggunakan cara yang susah ini untuk merepresentasikan bilangan negatif


memliki suatu arti dalam matematika jika kita menambahkan “-5” dengan “5” maka
kita dapatkan 0. Hal ini terjadi karena jika prosessor menambahkan dua byte 5 dan
251, maka hasilnya lebih dari 255. Karena terjadi verflow pada prosessor, sehingga
akan didapatkan angka 0

Jika kombinasi 128..255 selalu menggunakan 1 sebagai MSB, maka ini


memungkinkan untuk dapat digunakan menentukan tanda dari bilangan tersebut.
Dengan prinsip yang sama dapat digunakan words (nilai 16 bit), 16 bit menghasilkan
kombinasi sebesar 65536, 32768 kombinasi pertama (0..32767) digunakan untuk
merepresentasikan bilangan posistif, dam 32768 kombinasi lainnya (32768 – 65535)
mewakili bilangan negatif.

Ada cara mudah dalam emu8086 untuk mengkonversi bilangan, dan


membuat perhitungan dari tiap ekspresi numeric, yang diperlukan disini adalah klik
menu Math.
9

Base Converter mengizinkan kita untuk mengkonversi bilangan dari sistem nilai apa
saja ke sistem nilai lainnya. Ketik nilai di texbox, dan nilai akan secara otomatis
diubah ke semua sistem nilai. Dapat pula dipilih mode dalam nilai 8 bit atau 16 bit.

Multibase Calculator dapat digunakan untuk membuat kalkulasi diantara


bilangan yang mempunyai sistem nulai yang berbeda dan mengkonversinya dari
suatu sistem ke sistem lain. Ketik ekspresi dan tekan enter, hasilnya akan muncul
dalam sistem yang dipilih. Multibase Calculator dapa bekerja dengan nilai hingga 32
bit. Jika tanda Signed di check maka evaluator mengasumsikan bahwa semua nilai
(kecuali decimal dan double word) diperlakukan sebagai signed. Double Word selalu
diperlakukan sebagai suatu nilai signed, sehingga 0FFFFFFFFh dikoversi menjadi -1.

Misalnya kita ingin menghitung : 0FFFFh*10 + FFFFh. Jika kita check Signed
dan Word, akan didapatkan -17 (karena dievaluasi sebagai (-1) * 16 + (-1). Untuk
membuat kalkulasi dengan nilai Unsigned, jangan check tanda Signed sebagan
evaluasunya menjad 65535 * 16 + 65535 dan seharusnya didapat nilai 1114095. Kita
juga dapat menggunakan base converter untuk mengkonversi digit non-desimal ke
nilai decimal signed, dam melakukan kalkulasi dengan nilai decimal.
10

Operasi-operasi yang mendukung adalah

~ not (invert semua bit)

* perkalian

/ pembagian

% modulus

+ penambahan

- Pengurangan

<< Geser kiri

>> Geser kanan

& Bitwisw AND

^ Bitwise XOR

| Bitwire OR

Bilangan biner harus mempunyai suffix “b” contoh: 00011011b, bilangan


heksadesimal harus mempunyai suffix “h” dan dimulai dengan 0 jika digit pertama
adalah symbol huruf (A..F), contoh 0ABCDh. Bilangan octal harus memiliki suffix “o”
contoh : 77o.
11

Bahasa Assembly
Bahasa assembly merupakan bahasa pemrograman tingkat rendah.
Diperlukan menguasaan materi pengetahuan mengenai struktur komputer untuk
mengerti bahasa assembly. Model komputer sederhana dapat dilihat Gambar 1
berikut.

Seperti yang terlihat pada Gambar 1, sistem bus menhubungkan berbagai


komponen komputer. CPU merupakan jantung pusat dari komputer, dimana
sebagian besar dari perhitungan terjadi didalam CPU. RAM adalah tempat dimana
program dimuatkan dengan tujuan untuk dijalankan/ dieksekusi.
12

CPU 8086 memiliki 8 general purpose register, seperti dijelakan dalam Gambar 2.
Masing-masing register memiliki nama masing-masing.

 AX  Accumulator register (terbagi menjadi AH/ AL)

 BX  base address register (terbagi menjadi BH/ BL)

 CX  count register (terbagi menjadi CH/ CL)

 DX  data register (terbagi menjadi DH/ DL)

 SI  source index register

 DI  Destination Index register

 BP  Base Pointer

 SP  Stack Pointer

Fungsi utama dari register adalah untuk menyimpan variable, atau data. Ukuran
register-register yang disebutkan diatas adalah 16 bit. Register AX, BX, CX, DX terdiri
dari 2 register yang terpisah 8 bit, sebagai contoh jika AX = 0011 0000 0011 1001b,
maka AH = 00110000b dan AL = 00111001b ( “H” menyatakan high dan “L”
menyatakan Low). Oleh karena itu, ketika anda mengubah salah satu register 8 bit
maka register 16 bit juga diperbaharui, dan begit sebaliknya. Begitu pula untuk
register BX, CX, dan DX.

Karena register terletak didalam CPU, maka ia jauh lebih cepat daripada
memori. Pengaksessan lokasi memori memerlukan penggunaan sistem bus,
sehingga memakan waktu lebih lama. Menggakses data dalam register biasanya
membutuhkan waktu. Oleh karena itu, anda harus mencoba untuk menjaga variable
dalam register. Set register sangatlah kecik dan kebanyakan register mempunyai
tujuan khusus yang membatasi penggunaanya sebagai variable, tetapi masih
merupakan tempat yang sangat baik untuk menyimpan data sementara dari suatu
perhitungan.

Register Segmen

 CS  menunjuk pada segmen yang berisi program yang berjalan


13

 DS  umumnya menunjuk pada bagian dimana variable didefenisikan

 ES  register segmen tambahan, terserah programmer untuk menentukan


penggunaanya

 SS  menunjuk pada segmen yang berisi stack

Meskipun memungkinkan untuk menyimpan data dalam register segemen, hal ini
bukanlah merupakan ide yang baik. Register segrmen memiliki tujuan yang sangat
khusus – menunjuka pada blok yang diakses dari memori.

Register segmen bekerja sama dengan general purpose register untuk


mengakses nilai memori. Sebagai contoh juka kita ingin mengakses memori pada
alamat fisik 1234h (heksadesimal), kita harus mengatur DS = 1230h dan SI = 0045h.
ini bagus, karena dengan cara ini kita dapat mengakses memori lebih banyak
dibandingkan dengan satu register yang terbatas pada nilai 16 bit. CPU membuat
perhitungan alamat fisik dengan mengalihkan segmen register dengan 10h dan
menambahkan general purpose register untuk hal itu

(1230h * 10h + 45h = 12345h);

Alamat dibentuk oleh 2 register dan disebut alamat yang efektif. Secara default,
register BX, SI dan DI bekerja dengan register segmen DS; BP dan SP bekerja dengan
register segmen SS. General purpose register tidak dapat membentuk alamat efektif
dan juga meskipun BX dapat membentuk alamat efektif, BH dan BL tidak bisa.

Special Purpose Register

- IP  penunjuk instruksi

- Flag register  menentukan current state mikroprosessor

IP register selalu bekerja sama dengan register segmen CS dan ini menunjuk ke
instruksi yang sedang dijalankan. Flag register diubah secara otomatis oleh CPU
setelah operasi matematika, hal ini memungkinakan untuk menentukan jenis
14

hasilnya, dan untuk menentukan kondisi untuk mentransfer control ke bagian laian
dari program tersebut. Umumnya anda tidak dapat mengakses langsung register,
cara anda dapat mengakses AX dan register umum lainnya, tetapi adalah mungkin
untuk mengubah nilai dari register sistem menggunakan beberapa trik yang akan
dipelajari kemudian.
15

Modul I
Akses Memory

Untuk mengakses memori kita dapat menggunakan empat register : BX, SI, DI
dan BP. Dengan menggabungkan register di dalam symbol [ ]. Kita bisa
mendapatkan lokasi memori yang berbeda. Kombinasi ini didukung (mode
pengalamatan)

D8  merupakan penggantian nilai yang terdekat untuk 8 bit signed (misalnya: 22,
55h, -1, dll, ..)

D16  merupakan penggantian nilai yang terdekat untuk 16 bit signed (misalnya:
300, 5517h, -259, dll,,)

Pengggantian (displacement) dapat berupa nilai langsung (Immediate value)


atau offset variable, atau bahkan keduanya. Jika ada beberapa nilai, assembler
mengevaluasi semua nilai dan menghitung nilai langsung tunggal (single immediate
value). Penggantian bisa didalam atau diluar symbol [ ], assembler menghasilkan
kode mesin yang sama untuk kedua cara tersebut. Penggantian nilai yang bertanda
(signed value), dapat dilakukan baik pada nilai positif atau negatif.

Umumnya compile memperhatikan rentang perbedaan antara D8 dan D16,


dan menghasilkan kode mesin yang dibutuhkan. Misalnya, mari kita asumsikan
16

bahwa DS = 100, BX = 30 , SI = 70. Mode pengalamatan adalah [BX + SI] + 25.


Dihitung oleh prosessor ke alamat fisik (physical address) : 100 * 16 + 30 + 70 +25 =
1725. Secara default register segmen DS digunakan untuk semua mode kecuali
dengan register BP, untuk hal tersebut register segmen SS digunakan. Ada cara
mudah untuk mengingat semua kombinasi yang mungkin mengggunakan table
berikut:

Anda dapat membentuk semua kombinasi yang berlaku dengan mengambil


hanya satu item dari masing-masing kolom atau melewatkan kolom dengan tidak
mengambil apa-apa dari itu. Seperti yang anda lihat, BX dan BP tidak pernah
digunakan bersama-sama. SI dan DI juga demikian. Berikut merupakan contoh dari
mode pengalamatan yang valid [BX + 5 ], [BX + SI], [DI + BX – 4].

Nilai dalam register segmen (CS, DS, SS, ES) disebut segmen, dan nilai dalam
register tujuan (BX, SI, D, BP) disebut offset. Ketika DS berisi nilai 1234h dan SI berisi
nilai 7890h bisa juga dicata bahwa 1234:7890. Alamat fisik akan menjadi 1234h *
10h + 7890h = 19BD0h. jika no ditambahkan ke angka decimal, lalu dikalikan dengan
10 maka 10h = 16, jadi jika 0 ditambahkan ke nilai heksadesimal, maka dikalikan
dengan 16, misalnya:
7h = 7
70h = 7 * 16 = 112
Untuk menyatakan pada compiler tentang tipe data, prefix ini harus digunakan
BYTE PTR – untuk byte
WORD PTR – untuk word (2 byte)
Sebagai contoh

BYTE PTR [BX] ; akses byte


WORD PTR [BX] ; akses word
Assbler mendukung prefix yang lebih pendek seperti;
b. – untuk BYTE PTR
w. – untuk WORD PTR
17

pada kasus tertentu assembler dapat menghitung tipe data secara otomatis.

Instruksi MOV
- Menyalin operan kedua (sumber) ke operan pertama (tujuan)
- Operan sumber dapat menjadi nilai langsung (immediate value), general
purpose register atau lokasi memori
- Register tujuan dapat berupa sebuah general purpose register, atau lokasi
memori
- Kedua operan harus berukuran sama, yang dapat berupa byte atau word.

Instruksi MOV tidak dapat digunakan untuk mengatur nilai dari register CS dan IP.
18

Anda dapat mencopi & paste program diatas code editor, dan tekan tombol
[Compile and Emulate] atau tekan tombol F5 pada keyboard anda. Jendela emulator
seharusnya tampil saat program ini dimuat, klik tombol [Single Step] dan berhatikan
nilai-nilai register.

Bagaimana melakukan copy & paste:


1. Pilih teks diatas menggunakan mouse, klik sebelum teks dan tarik ke bawah
sampai semuanya dipilih
2. Tekan kombinasi CTRL+C untuk menyalin
3. Beralih ke source editor dan tekan combinasi CTRL + V untuk paste
Tanda “;” digunakan untuk komentar, tulisan / symbol apapun setelah “;” diabaikan
oleh compiler. Maka tampilan program seharusnya sebagai berikut.

Sebenarnya program diatas menulis langsung ke video memori, jadi anda dapat
melihat bahwaa MOV merupakan instruksi yang powerful.
19

Modul II
Variabel

Variabel adalah suatu lokasi di dalam memori. Bagi seorang programmer


akan lebih mudah memiliki suatu nilai yang disimpan pada variable dengan nama
“var1” daripada alamat 5A73:235B, khusunya jika anda memiliki 10 atau lebih
variable. Compiler emu8086 mendukung tua tipe variable :BYTE dan WORD.
Syntax deklarasi variable

name DB value
name DW value

DB – kependekan dari Define Byte


DW – kependekan dari Define word

name – kombinasi dari alphanumeric, diawali dengan huruf. Mungkin juga tidak
bernama (maka hanya punya alamt saja)

value – berupa nila numeric yang didukung oleh sistem nilai (heksadesimal, biner,
atau decimal), atau symbol “?” untuk veriabel yang tidak diinisialisasi.

Instruksi MOV digunakan untuk mengnyalin nilai dari sumber ke tujuan. Berikut
contoh lain instruksi MOV

ORG 100h

MOV AL, var1


MOV BX, var2

RET ; stop the program

VAR1 DB 7
VAR2 DW 1234h
20

Tulikan kode diatas pada editor emu8086 dan tekan F5 untuk compile dan memuat
ke emulator, hasilnya seharusnya akan terliha sebagai berikut:

Dapat anda lihat seperti yang dicontohkan, kecuali variable diganti dengan lokasi
actual pada memori. Saat compiler membuat kode mesin, hal tersebut secara
otomatis menggantu semua variable dengan alamat offset. Secara default segment
di load didalam register DS ( jika file .COM nilai yang diload pada register DS di set
sama dengan nilai pada register CS - Code Segment.

Kolom pertama pada memori adalah sebuah offser, kolom kedua adalah
suatu nilai heksadesimal, kolom ketiga adalah nilai decimal, dam yang terakhir
21

adalah karakter ASCII. Compiler tidak case sensitive, jadi “VAR1” dan “var1”
mengacu pada variable yang sama. Offset dari VAR1 adalah 0108h, dan alamat
lengkapnya adalah 0B56h:0108h. offset dari var2 adalah 0109h, alamt lengkapnya
adalah 0B56h:0109. Variable ini bertipe WORD sehingga perlu 2 byte, hal tersebut
diasumsikan bahwa low byte (byte) rendah disimpan pada alamat yang lebih rendah
(lower address), sehingga 34h berada sebelum 12h. dapat anda lihat bahwa ada
suatu instruksi lainnya setelah instruksi RET, ini terjadi karena diassemble tidak tahu
dimana data dimulai, dia hanya memproses nilai dalam memori dan memahami
sebagai instruksi 8086 yang sah, (akan dipelajari kemudian). Anda bahkan dapat
menulis program yang sama menggunakan directif DB.

ORG 100h
DB 0A0h
DB 08h
DB 01h

DB 8Bh
DB 1Eh
DB 09h
DB 01h

DB 0C3h

DB 7
DB 34h
DB 12h

Tulis program diatas dalam source editor. Dan tekan F5 untuk diload kedalam
emulator. Hasilnya seharusnya sama dengan kode diassemble, dan berfungsi sama.

Seperti yang anda duga, compiler hanya mengkonversi source code ke dalam byte,
yang disebut dengan machine code, prosessor hanya mengerti machine code dan
menjalankannya.

ORG 100h adalah directive compiler (yang mengatakan pada compiler bagaimana
menangani source code). Directive ini sangat penting saat kita bekerja dengan
22

variable. Directive tersebut mengatakan pada compile bahwa file executable akan
diload pada alamat offset 100h (256 bytes). Jadi compiler harus menghitung alamat
yang benar untuk semua variable ketika ia akan mengganti nama variable dengan
nama offset. Directive tidak pernah dikonversi ke machine code.

Mengapa file executable diload pada offset 100h? sistem operasi menjaga semua
data tentang program dalam 256 byte pertama dari CS (code segment), seperti
misalnya parameter command line dan sebagainya. Meskipun memang benar hanya
bagi file .COM, file .EXE diload pada offset 0000, dan umumnya menggunakan
segment khusus untuk variable.

Array
Array dapat dilihat dan diterjemahkan sebagai suatu rantai variable. Text string
merupakan contoh dari array byte, masing-masing karakter diwakili sebuah nilai
kode ASCII (0…256), contohnya:

a DB 48h, 65h, 6ch, 6ch, 6fh, 00h,


b DB ‘Hello’ , 0

b adalah salinan yang sebenarnya dari array a, ketika compiler melihat string yang
didalam tanda petik, secara otomatis akan mengkonversinya kedalam byte. Gambar
dibawah ini menunjukkan bagian memori dimana array dideklarasikan.

Anda dapat mengakses nilai tiap elemen dalam array menggunakan kurung kotak,
contohnya:
MOV AL, a[3]
Anda juga dapat menggunakan memori index register BX, SI, DI, BP, contohnya:
MOV SI, 3
MOV AL, a[SI]
23

Jika anada perlu mendeklarasikan array yang lebih besar, dapat anda gunakan
operator DUP, syntak DUP:
number DUP (value (s) )
number  banyak duplikasi yang akan dibuat (nilai konstan)
value  ekspresi yang akan diduplikasi oleh DUP

sebagai contoh:
C DB 5 DUP (9)

Instruksi diatas memiliki arti yang sama dengan

C DB 9, 9, 9, 9, 9
Contoh lain;
d DB 5 DUP (1, 2)

memiliki arti yang sama dengan instruksi berikut

d DB 1, 2, 1, 2, 1, 2, 1, 2, 1, 2

Tentu saja kita dapat menggunakan DW sebagai pengganti dari DB, jika diperlukan
untuk menjaga nilai yang lebih besar dari 255 atau lebih kecil dari -128. Namun
demikian , DW tidak dapat digunakan untuk mendeklarasikan string.

Mendapatkan alamat suatu variable

Ada suatu instruksi yaitu LEA (Load Effective Address) yang merupakan laternatif dari
operator offset. Baik offset dan LEA dapat digunakan untuk mendapatkan offset
address dari suatu variable. LEA bahkan lebih powerful karena ia juga mendapatkan
alamat dari index variabelnya. Mendapatkan alamat dari suatu variable bisa menjadi
sangat berguna dalam suatu situasi misalnya saat kita akan mengirim parameter ke
suatu prosedur, contohnya;
24

Berikut contoh lain penggunaan offset sebagai pengganti LEA.


25

Kedua contoh diatas memiliki fungsi yang sama, perhatikan;

LEA BX, VAR1


MOV BX, OFFSET VAR1

Akan dikompile ke dalam kode mesin yang sama dengan;


MOV BX, num

num adalah nilai 16 bit dari variable Offset

Perlu dicatat bahwa hanya register ini yang dapat digunakan dalam kurung kotak
seperti pointer memori: BX, SI, DI, BP.

Konstanta
Konstanta keberadaanya hampir sama dengan variable, namun keberadaanya hanya
sampai program dikompilasi (assemble). Setelah defenisi sebuah konstanta, nilai
yang ditentukan tidak dapat dirubah. Untuk mendeklarasikan sebuah konstanta
digunakan directif EQU.

name EQU <any expression>


contoh:
k EQU 5
MOV AX, k

Contoh diatas memiliki fungsi yang sama dengan kode

MOV AX, 5

Anda dapat melihat variable sementara program yang sedang dieksekusi dengan
memilih “Variabel” dari menu “View” dari emulator.

Untuk melihat array, klik pada variable dan mengeset property Element untuk
ukuran array. Dalam bahasa assembly tidak ada batasan tipe data, maka setiap
variable dapat direpresentasikan sebagai suatu array. Variable dapat dilihat dalam
beberapa sistem nilai.
26

- HEX – Heksadeimal (basis 16)


- BIN – biner (basis 2)
- OCT – Octal (basis 8)
- Signed – signed decimal (base 10)
- Unsigned – unsigned decimal (base 10)
- CHAR – ASCII Char kode (ada 256 simbol, beberapa symbol tidak terlihat.
Anda dapat mengedit nilai variable saat program sedang berjalan, double click pada
variable tersebut, atau pilih dan klik tombol edit. Adalah hal yang memungkinkan
untuk memasukkan angka pada setiap sistem, nila heksadesimal harus mempunyai
suffix “h”, biner “b”, octal “o”, nilai decimal tidak memerlukan suffix. String dapat
dimasukkan dengan cara berikut: ‘hello word’, 0 (string diakhiri dengan 0)

Array dapat dimasukkan dengan:


1, 2, 3, 4, 5
(array dapat berupa byte atau word, tergantung pada BYTE atau WORD yang dipilih
saat mengedit variable).

Ekspresi secara otomatis dikonversi, contoh, saat ekspresi dimasukkan: 5+2 akan
dikonversi ke 7 dll.
27

Modul III
Interupsi

Interupsi dapat dipandang sebagai sejumlah fungsi. Fungsi-fungsi ini


memudahkan pemrograman, bahkan untuk menulis kode mencetak karakter. Anda
dapat dengan mudah memanggil interupsi yang bersesuaian dan melakukan fungsi
pada interupsi tersebut untuk anda. Ada juga fungsi interupsi yang bekerja pada disk
drive atau hardware lainnya. Pada saat anda memanggil suatu fungsi maka hal itu
dinamakan software interrupts. Interupsi yang dipicu oleh hardware lainnya disebut
hardware interrupts.

Saat ini kita akan membahas pada software interupsi, untuk membuat
software interrupt ada suatu instruksi yaitu INT, syntaknya adalah:

INT value

Dimana value berupa angka antara 0 – 255 (0h – FFh), umumnya kita menggunakan
angka heksadesimal. Anda mungkin berfikir hanya ada 256 fungsi, tapi sebenarnya
kurang tepat. Tiap interupsi masih memiliki subfunction. Untuk menentukan suatu
subfuction, register AH harus diset sebelum memanggil interupsi. Setiap interupsi
hampir memiliki 256 sub fungsi, sehingg total subfungsi yang dimiliki adalah 256 *
256 = 65536. Secara umum register AH yang digunakan, tapi suatu saat register lain
juga dipakai. Pada umumnya register lain digunakan untuk mengirim parameter dan
data ke subfuction.

Contoh berikut ini menggunakan INT 10h subfunction 0Eh untuk mencetak
pesan “Hello!”. Fungsi ini menampilkan karakter dilayar. Compile dan emulator lalu
eksekusi program.
28
29

Modul IV
Library of Common Function

Untuk membuat pemrograman lebih mudah, ada beberapa fungsi umum


yang disertakan dalam program. Untuk membuat program kita menggunakan fungsi
yang didefenisikan pada file lainnya kita harus menggunakan directive INCLUDE,
diikuti dengan nama file yang diacu. Compiler secara otomatis mencari file tersebut
pada folder yang sama dimana file sumber diletakkan, dan jika tidak ditemukan,
maka compiler akan mencari di folder Inc. Saat ini mungkin anda belum paham
benar isi dari emu8086.inc. (file yang berada pada folder Inc), tapi tidak masalah,
karena yang kita butuhkan adalah apa yang dapat dikerjakannya. Untuk memakai
fungsi dalam emu8086.inc kita harus memiliki baris dalam kode didalam source
seperti ini;
Include ‘emu8086.inc’

Emu8086.inc mendefeniskan banyak macro sebagai berikut;


- PUTC char  macro dengan 1 parameter, mencetak sebuah karakter ASCII
pada posisi kursor sekarang.
- GOTOXY col, row  macro dengan 2 parameter, mengeset posisi kursor.
- PRINT string  macro dengan 1 parameter, mencetak sebuah string
- PRINTN string  macro dengan 1 parameter, mencetak string. Sama dengan
macro PRINT tetapi otomatis menambahkan “carriage return” diakhir string
- CURSOROFF  mematikan kursor text
- CURSORON  Menghidupkan kursor text

Untuk menggunakan macro diatas, tinggal ketik nama macro dan parameter yang
dibutuhkan, contohnya:
30

Saat compiler memproses kode kita, dia mencari file emu8086.inc untuk macro yang
dideklarasikan dan menggantikannya dengan nama macro dalam kode yang
sebenarnya. Umumnya macro relative bagian yang kecil dalam kode, keseringan
menggunakan macro menyebabkan pengeksekusian kita menjadi besar, penggunaan
prosedur lebih dianjukan untuk optimasi ukuran program. Emu8086.inc juga
mendafeniskan prosedur sebagai berikut.
- PRINT_STRING  prosedur untuk mencetak null terminater string pada
posisi kursor saat ini, menerima alamat string dalam register DS:SI. Untuk
menggunakannya deklarasikan DEFINE_PRINT_STRING sebelum directive
END.
- PTHIS  Prosedur untuk mencetak null terminated string pada posisi kursor
saat ini (seperti PRINT_STRING), tetapi menerima alamat string dari Stack.
ZERO terminated string yang harus didefenisikan setelah instruksi CALL,
contohnya;
CALL PTHIS
DB ‘Hello Word!’, 0
Untuk menggunakannya deklarasikan: DEFINE_PTHIS sebelum directive END.
31

- GET_STRING  Prosedure untuk mendapatkan input null terminated string


dari user, string yang diterima disimpan dalam buffer di register DS:SI,
ukuran buffer berada di DX. Prosedur ini menghentikan input saat tombol
‘Enter’ ditekan. Cara menggunakannya; DEFINE_GET_STRING sebelum
directive END.
- CLEAR_SCREEN  prosedur membersihkan layar, sebenarnya hanya
menggulung layar saja satu windows). Dan mengeset posisi kursor
diatasnya. Cara pemakaiannya: DEFINE_CLEAR_SCREEN setelah directive
END.
- SCAN_NUM  prosedur untuk menerima input berupa angka multi digit
SIGNED(bertanda) dari keyboard. Dan menyimpan hasilnya deregister CX.
Cara pemakaianya DEFINE_SCAN_NUM sebelum directive END.
- PRINT_NUM  prosedur mencetak angka signed dalam register AX.
Pemakaianya : DEFINE_PRINT_NUM dan DEFINE_PRINT_NUM_UNS sebelum
directive END.
- PRINT_NUM_UNS  prosedur untuk mencetak angka unsigned dalam
register AX, pemakaiannya: DEFINE_PRINT_NUM_UNS sebelum directif END.

Untuk menggunakan semua prosedur diatas kita harus mendeklarasikan fungsi


dibawah file sumber (sebelum directive END), dan kemudian menggunakan instruksi
CALL diikuti dengan nama prosedur contohnya;

Include emu8086.inc
ORG 100h

LEA SI, msg1 ; ask for the number


CALL PRINT_STRING
CALL SCAN_NUM ; get number ini CX

MOV AX, CX ; copy the number to AX

; print following string


CALL PTHIS
DB 13, 10, ‘You Have Entered: ‘ , 0

CALL PRINT_NUM ; print number in AX


32

RET ; return to operating system


msg1 DB ‘Enter the number:’ , 0

DEFINE_SCAN_NUM
DEFINE_PRINT_STRING
DEFINE_PRINT_NUM
DEFINE_PRINT_NUM_UNS ; required for PRINT_NUM
DEFINE PTHIS

END ; directive to stop compiler

Pertama-tama compiler memproses deklarasi (ada makro biasa yang diekspansi


menjadi prosedur), saat compiler menerima instruksi CALL, ia mengantikan alamat
prosedur dengan alamat dari kode dimana prosedur dideklarasikan. Saat instruksi
CALL mengeksekusi control maka procedure dipindahkan. Hal ini sangat berguna,
karena jika memanggil prosedur 100 kali dalam kode program kita masih
mempunyai ukuran program yang kecil.
33

MODUL V
Instruksi aritmatika dan Logika

Setiap instruksi arimatika dan logika berpengaruh pada flag register di prosessor.

Dalam register 16 bit, tiap bit flag disebut flag dan dapat bernilai 1 atau 0
- Carry Flag (CF) – flag ini diset ke 1 jika ada unsigned overflow. Contoh saat
kita menambah byte 255 + 1 (hasilnya tidak dijangkauan 0..255). Saat tidak
ada overflow, flag ini diset 0.
- Zero Flag (ZF) – diset 1 jika hasilnya 0, untul hasil selain 0 flag diberi nilai 0.
- Sign Flag (SF) – diset 1 jika hasilnya negatif, saat hasilnya positif diset ke 0.
Sebenarnya flag ini mengambil nilai dari MSB (Most Significant Byte)
- Overflow Flag (OF) – diset ke 1 saat ada signed overflow, contohnya jika
menambah byte 100 + 50, hasinya tidak diluar -128…127.
- Parity Flag (PF) – diset ke 1 jika ada angka genap dari satu bit dalam hasilnya,
dan di set 0 jika ada angka ganjil. Jika hasilnya berupa word hanya 8 digil low
yang dianalisis.
- Auxiliary Flag (AF) – diset 1 jika unsigned overflow untuk low nibble (4bit)
- Interrupt Enable Flag (IF) – jika flag diset 1 CPU mendapatkan interupsi dari
piranti eksternal
- Direction Flag (DF) - flag ini digunakan oleh beberapa instruksi untuk
memproses rantai data, jika flag diset ke 0 – proses diselesaikan ke depan,
jika flag bernilai 1 proses diselesaikan ke belakang.
34

Ada 3 kelompok instruksi;


Kelompok pertama; ADD, SUB, CMP, AND, TEST, OR, XOR
Tipe operan yang mendukungnya
REG, memory
memory, REG
REG, REG
memory, immediate
REG, immediate
REG: AX, BX, CX, DX, AH, AL, BL, BH, CH, CL, DH, DL, DI, SI, BP, SP.
memory: [BX], [BX+SI+7], variable, etc...
immediate: 5, -24, 3Fh, 10001101b, etc...

Setelah operasi diantara operan, hasilnya selalu disimpan dioperan pertama.


Instruksi CMP dan TEST hanya berakibat pada flag register dan tidak menyimpan
hasilnya (instruksi ini digunakan untuk membuat keputusan selama eksekusi
program.

Instruksi – instruksi yang berpengaruh hanya pada flag:


CF, ZF, SF, OF, PF, AF
- ADD  menambahkan operan kedua ke operan pertama
- SUB  mengurangi operan pertama dengan operan ke dua
- CMP  membandingkan kedua operan, dan hasilnya mempengaruhi register
flag
- AND  Logika AND antara semua bit dari kedua operan
Aturannya:
1 AND 1 = 1
1 AND 0 = 0
0 AND 1 = 0
0 AND 0 = 0
Kita dapatkan 1 hanya jika kedua bit operan bernilai 1
- TEST  Sama dengan AND tapi perubahan hanya terjadi pada register flag
- OR  Logika OR antara semua bit dari dua operan
Aturannya:
1 OR 1 = 1
1 OR 0 = 1
35

0 OR 1 = 1
0 OR 0 = 0
Kita dapatkan 1 hanya jika salah satu atau kedua bit operan bernilai 1
- XOR  Logika XOR (exclusive OR) antara semua bit dari dua operan
Aturannya:
1 XOR 1 = 0
1 XOR 0 = 1
0 XOR 1 = 1
0 XOR 0 = 0

Kelompok Kedua : MUL, IMUL, DIV, IDIV


Tipe operan yang mendukungnya:
REG
Memory

REG : AX, BX, CX, DX, AH, AL, BL, BH, CH, CL, DH, DL, DI, SI, BP, SP.
Memori : [BX], [BX+SI+7], variable, etc...

Intruksi MUL dan IMUL hanya mempengaruhi flag : CF dan OF


Jika hasilnya diatas ukuran operan, flag diset 1, jika tidak flag diset 0. Untuk flag yang
dipengaruhi operasi DIV dan IDIV tidak didefenisikan.
- MUL  Perkalian unsigned
Jika operannya byte:
AX = AL * Operan
Jika operannya word:
(DX AX) = AX * operan
- IMUL  perkalian Signed
Jika operannya byter
AX = AL * operan
Jika operannya word
(DX AX) = AX * operan
- DIV  Pembagian Unsigned
Jika operannya byte :
AL = AX / operan
AH = remainder
36

Jika operannya word


AX = (DX AX) / operan
DX = remainder
- IDIV  pembagian signed
Jika operannya byte :
AL = AX / operan
AH = remainder
Jika operannya word
AX = (DX AX) / operan
DX = remainder

Kelompok ketiga: INC, DEC, NOT, NEG


Tipe operan yang mendukung :
REG
Memory
REG : AX, BX, CX, DX, AH, AL, BL, BH, CH, CL, DH, DL, DI, SI, BP, SP.
memory: [BX], [BX+SI+7], variable, etc...

- Instruks INC, DEC hanya mempengaruhi flag: ZF, SF, OF, PF, AF.
- Instruksi NOT tidak mempengaruhi flag apapun,
NOT = kebalikan untuk setiap bit
- Instruksi NEG hanya mempengaruhi flag CF, ZF, SF, OF, PF, AF.
NEG : membuat operan menjadi negatif (bilangan komplemen 2).
Sebenarnya dicadangkan untuk setiap bit operand an ditambahkan 1, contoh
5 menjadi -5 dan 2 menjadi -2.
37

Modul VI
Aliran Kendali Program

Pengendalian alur program merupakan bagian yang penting. Disini program kita
dapat menentukan keputusan berdasarkan kondisi.

1. Unconditional Jump
Instruksi dasarnya adalah bahwa mengendalikan transfer dari suatu titik ke titik
lainnya didalam program, yaitu instruksi JMP, sintaksnya:
JMP label
Deklarasikan label dalam program, tulis namanya dan tambahkan “:” setelah nama
label, label berupa kombinasi karakter alphanumeric yang tidak dimulai dengan
angka, contoh:
Label2:
a
L1234:
Label dapat dideklarasikan pada baris terpisah atau sebelum instruksi lainnya,
contoh:
X1:
MOV AX, 1
Atau
X2 : MOC AX, 2
Contoh instruksi JMP:

ORG 100h
MOV AX, 5 ; set AX to 5.
MOV BX, 2 ; set BX to 2.
JMP calc ; go to 'calc'.
Back: JMP stop ; go to 'stop'.
calc:
ADD AX, BX ; add BX to AX.
JMP back ; go 'back'.
stop:
RET ; return to operating system.
END ; directive to stop the compiler.
38

Tentu saja ada cara mudah untuk mengkalkulasikan dua angka, tetapi contoh diatas
merupakan contoh yang sudah cukup baik mengenai penggunaan instruksi JMP.
Seperti terlihat dari contoh diatas JMP dapat mentransfer kendali baik secara
forward dan backward. Ia dapat melompat kemanapun dalam code segmen (65536
bytes)

2. Short Conditional Jump


Tidak seperti instruksi JMP yang merupakan instruksi ini mengerjakan unconditional
jump. Terdapat juga instruksi unconditional jump, dimana kendali aliran akan
melompat hanya jika kondisi terpenuhi. Instruksi ini dibagi menjadi 3 kelompok,
yaitu:
- Instruksi yang menguji flag tunggal
- Instruksi membandingkan angka sebagai signed
- Instruksi membandingkan angka sebagai unsigned

Instruksi Jump dalam menguji flag tunggal

Seperti terlihat ada instruksi yang mengerjakan hal yang sama, perlu diingat bahwa
jika kita mengkompile instruksi JE kita akan mendapatkan disassemble sebagai JX, JC
adalah assembled yang sama dengan JB dan sebagainya, perbedaan mana
39

digunakan untuk membuat program lebih mudah dimengerti, lebih muda


mengkodekan dan yang paling penting adalah mudah diingat. Setiap offset yang
diassembler tidak mempunyai petunjuk instruksi aslinya seperti apa. Oleh karena itu
digunakan nama yang umum. Jika kita mengemulasi kode ini kita akan melihat
seluruh instruksi diassemble kedalam JNB, operational code (opcode) untuk instruksi
ini adalah 73h instruksi ini mempunyai panjang tetap dua byte, byte kedua
merupakan angka dari byte tersebut ditambah ke register IP jika kondisinya
terpenuhi. Karena instruksi ini hanya mempunyai 1 byte untuk menyimpan offset
yang terbatas untuk mengirim control ke -128 byte ke belakang atau 127 bytes ke
depan, nilai ini selalu signed.

JNC a
JNB a
JAE a
MOV AX, 4
a: MOV AX, 5
ret

Instruksi jump untuk angka signed


40

Instruksi jum untuk angka unsigned

Umumnya, jika diperlukan untuk membandingkan nilai numeric instruksi CMP


digunakan (sama dengan instruksi SUB, tetapi tidak menyimpan hasilnya, hanya
berpengaruh pada flagnya saja).
Logikanya sederhana:
Contoh
- Bandingkan 5 dan 2 , 5 -2 = 3
Hasilnya bukan nol sehingga zero flag diset ke 0
- Bandingkan 7 dan 7, 7 – 7 = 0
Hasilnya nol sehingga zero flag diset 1 dan JZ atau JE tidak melompat.
Contoh instruksi CMP pada conditional jump

include emu8086.inc
ORG 100h
MOV AL, 25 ; set AL to 25.
MOV BL, 10 ; set BL to 10.
CMP AL, BL ; compare AL - BL.
JE equal ; jump if AL = BL (ZF = 1).
PUTC 'N' ; if it gets here, then AL <> BL,
41

JMP stop ; so print 'N', and jump to stop.


equal: ; if gets here,
PUTC 'Y' ; then AL = BL, so print 'Y'.
stop:
RET ; gets here no matter what.
END

Cobalah contoh diatas dengan angka yang lain untuk AL dan BL, buka flag dengan
mengklik tombol flag, gunakan single step dan lihat yang terjadi. Kita juga dapat
memakai F5 untuk mengcompile ulang dan memuat ulang program ke emulator.

3. Kalang (Loop)

Pada dasarnya loop sama dengan jump, mungkin saja mengkodekan loo tanpa
menggunakan instruksi loop dengan hanya menggunakan jump dan compare dan
memang seperti inilah loop bekerja. Semua instruksi loop menggunakan register CX
untuk menghitung langkah, seperti diketahui register CX memiliki 16 bit dan nilai
maksimum dapat menjangkau 65535 atau 0FFFFh. Bagaimanapun juga dapat saja
meletakkan loop dalam loop sehingga nilai jangkaiannya dapat sebesar 65535 *
65535 * 65535 hingga batas stack RAM penuh. Dimungkinkan menyimpan nilai asli
pada register CX dengan instruksi PUSH CX dan mengembalikannya ke asalnya jika
internal loop berakhir dengan pop CX, contohnya:
42

ORG 100h
MOV BX, 0 ; total step counter
MOV CX, 5
K1 : ADD BX, 1
MOV AL, ‘1’
MOV AH, 0Eh
INT 10h
PUSH CX
MOV CX, 5
K2 : ADD BX, 1
MOV AL, ‘2’
MOV AH, 0Eh
INT 10h
PUSH CX
MOVE CX, 5
K3 : ADD BX, 1
MOV AL, ‘3’
MOV AH, 0Eh
INT 10h
LOOP K3 ; internal in internal loop
POP CX
LOOP K2 ; internal loop
POP CX
LOOP K1 ; external loop
RET

Semua conditional jump memiliki satu batasan yang besar, tidak seperti instruksi
JMP mereka hanya bisa melompat sebesar 127 bytes kedepan dan 128 bytes ke
belekang. Batasan ini dapat diatasi dengan trik
- Ambil instruksi lawan conditional jump dari table diatas lalu jump ke label_x
- Gunakan instruksi JMP untuk melompat ke lokasi yang diinginkan
- Buat label_x setelah instruksi JMP
Contoh:
43

Include “emu8086.inc”
ORG 100h
MOV AL, 5
MOV BL, 5
CMP AL, BL ; bandingkan AL dengan BL
JE EQUAL ; hanya ada 1
JNE NOT_EQUAL ; jump jika al <>bl (zf = 0)
JMP EQUAL
NOT_EQUAL :
ADD BL, AL
SUB AL, 10
XOR AL, BL
JMP SKIP_DATA
DB 256 DUP (0) ; 256byte
SKIP_DATA:
PUTC ‘n’ ; jika disini, maka AL <> BL
JMP STOP ; cetak ‘n’ dan jump ke stop
EQUAL: ; jika disini
PUTC ‘y’ ; maka AL = BL, jadi cetak ‘y’
STOP:
RET

Contoh lainnya, menggunakan metode yang disediakan nilai terdekat dalam label.
Jika nilai terdekat diawali $ maka jump dilakukan, jika tidak compiler menghitung
instruksi dimana jump secara langsung diberikan ke offset, contoh;
ORG 100h
; unconditional jump forward
; skip over next 3 byte + itself
; the machine code of short jump instruction take 2 bytes
JMP $3 + 2
a DB 3 ; 1 byte
b DB 4 ; 1 byte
c DB 4 ; 1 byte
; Conditional jump back 5 bytes
MOV BL, 9
DEC BL ; 2 bytes
44

CMP BL, 0 ; 3 byte


JNE $ - 5 ; jump 5 byte bac
RET
45

MODUL VII
PROSEDUR

Prosedur merupakan bagian dari kode yang dapat dipanggil dari program dalam
rangka tugas tertentu. Prosedur membuat program lebih terstruktur dan mudah
dimengerti. Umumnya prosedur mengembalikan ke titik dimana dia dipanggil.
Syntaknya:

name PROC
; here goes the code
; of the procedure …
RET
name ENDP

name - nama prosedur, nama ini harus sama di awal dan di akhir prosedur.

RET menyatakan kembali ke sistem operasi setelah pemanggilan prosedur. PROC


dan ENDP merupakan directive compiler. Jadi tidak diassembled ke dalam kode
mesin. Compiler hanya mengingat alamat dari prosedur. Instruksi CALL digunakan
untuk memanggil prosedur.
Contoh:

ORG 100h

CALL m1
MOV AX, 2
RET ; return to operating system

m1 PROC
MOV BX, 5
RET ; return to caller.
m1 ENDP
END
46

Contoh diatas memanggil prosedur m1, yang mengerjakan MOV BX, 5, dan kembali
ke instruksi selanjutnya setelah CALL : MOV AX, 2

Ada beberapa cara untuk mengirim parameter ke prosedur, yang paling


mudah adalah mengirimkan parameter menggunakan register, disini contoh lainnya
dari prosedur menerima dua parameter dalam register AL dan BL, kalikan kedua
parameter dan kirim hasilnya ke register AX:

ORG 100h

MOV AL, 1
MOV BL, 2
CALL m2
CALL m2
CALL m2
CALL m2
RET ; return to operating system.
m2 PROC
MUL BL ; AX = AL * BL.
RET ; return to caller.
m2 ENDP
END

Dalam contoh diatas nilai register AL di update setiap saat prosedur dipanggil,
register BL tetap tidak berubah, jadi algoritma ini menghitung 2 pangkat 4, hasil
akhirnya deregister AX adalah 16 (or 10h). Contoh lainnya, prosedur mencetak
pesan Hello World!:

ORG 100h
LEA SI, msg ; load address of msg to SI.
CALL print_me
RET ; return to operating system.
;========================================================
; this procedure prints a string, the string should be
; null terminated (have zero in the end),the string
; address should be in SI register:
47

print_me PROC
next_char:
CMP b.[SI], 0 ; check for zero to stop
JE stop ;
MOV AL, [SI] ; next get ASCII char.
MOV AH, 0Eh ; teletype function number.
INT 10h ; using interrupt to print a char in
; AL.
ADD SI, 1 ; advance index of string array.
JMP next_char ; go back, and type another char.
stop:
RET ; return to caller.
print_me ENDP
;========================================================
msg DB 'Hello World!', 0 ; null terminated string.
END

Prefix “b.” sebelum [SI] berarti bahwa kita perlu membandingkan byte, bukan word.
Jika kita perlu membandingkan word tambahan prefix “w.”. Jika salah satu operan
pembandingnya berupa register, hal tersebut tidak diperlukan karena compiler tahu
ukuran tiap register.
48

MODUL VIII
STACK

Stack adalah suatu arean di memori yang menyimpan data sementara. Stack
digunakan dengan instruksi CALL untuk menyimpan alamat yang dikembalikan pada
prosedur, instruksi RET mengambil nilai ini dari stack dan mengembalikannya ke
offset. Hamper sama kejadiannya jika instruksi INT memanggil interupsi, dia
menyimpan register flag stack, kode segmen dan offset. Instruksi IRET digunakan
untuk mengembalikan dari pemanggil interupsi. Kita juga dapat menggunakan stack
untuk menyimpan data lainnya, ada dua instruksi yang bekerja dengan stack, yaitu:
PUSH – menyimpan nilai 16 bit dalam stack
POP – mengambil nilai 16 bit dari stack

Sintak untuk instruksi PUSH:


PUSH REG
PUSH SREG
PUSH memory
PUSH immediate
REG: AX, BX, CX, DX, DI, SI, BP, SP.
SREG: DS, ES, SS, CS.
memory: [BX], [BX+SI+7], 16 bit variable, etc...
immediate: 5, -24, 3Fh, 10001101b, etc...

Sintak untuk instruksi POP


POP REG
POP SREG
POP memory
REG: AX, BX, CX, DX, DI, SI, BP, SP.
SREG: DS, ES, SS, (except CS).
memory: [BX], [BX+SI+7], 16 bit variable, etc...

Catatan :
- PUSH dan POP bekerja dengan nilai 16 bit saja
- PUSH immediate bekerja hanya pada CPU 80186 dan sesudahnya.
49

Stack menggunakan algoritma LIFO ( Last In Fisrt Out), aartinya jika kita dorong nilai
satu per satu ke dalam stack:
1, 2, 3, 4, 5
Nilai pertama yang dapat kita POP adalah 5, lalu 4, 3, 2, dan terakhir 1.

Jumlah yang di PUSH dan di POP harus sama. Jika tidak stack akan corrupted dan
tidak dapat kembali ke OS. Kita gunakan instruksi RET untuk kembali ke OS. Jadi jika
program mulai ada alamat yang dikembalikan di stack (umumnya 0000h). instruksi
PUSH dan POP berguna karena tidak memiliki cukup register untuk dioperasikan,
triknya adalah:
- Simpan nilai original dari register dalam stack ( dengan PUSH)
- Pakai register untuk tujuan apapun
- Kembalikan nilai original register dari stack (dengan POP)
Contoh:

ORG 100h
MOV AX, 1234h
PUSH AX ; store value of AX in stack.
MOV AX, 5678h ; modify the AX value.
POP AX ; restore the original value of AX.
RET
END
50

Contoh lainya kegunaan stack dalam pertukaran nilai:

ORG 100h
MOV AX, 1212h ; store 1212h in AX.
MOV BX, 3434h ; store 3434h in BX
PUSH AX ; store value of AX in stack.
PUSH BX ; store value of BX in stack.
POP AX ; set AX to original value of BX.
POP BX ; set BX to original value of AX.
RET
END

Pertukaran terjadi karena stack memakai algoritma LIFO (Last In First Out). Jadi saat
kita PUSH 1212h dan kemudaian 3434h, pada saat POP kita mendapatkan yang
pertama 3434 kemudian 1212h. Area memori stack diset oleh register SS (Stack
Segment) dan register SP (Stack Pointer). Umumnya OS mengatur nilai register ini
saat program dimulai.
“PUSH Source” instruksi ini mengerjakan
- Kurangi 2 dari register SP
- Tulis nilai source ke alamat SS:SO
“POP destination” instruksi ini mengerjakan:
- Tulis nilai alamat SS:SP ke destination
- Tambahkan 2 ke register SP
Alamat sekarang ditunjuk oleh SS:SP yang dinamakan the top of the stack. Untuk file
.COM stack segment dapa umumnya berada di code segment,, dan stack pointer
diset pada nilai 0FFFEh. Pada alamat SS:0FFFE disimpan alamat kembalian untuk
instruksi RET yang dieksekusi pada akhir program. Klik tombol [Stack] pada emulator
window. Bagian atas stack ditandai dengan “<”.
51

MODUL IX
MAKRO

Macro hampir mirip dengan prosedur, tetapi bedanya ia hanya ada hingga kode
dikompilasi, setelah kompilasi dilakukan semua makro akan diganti dengan instruksi
mesin. Jika kita mendeklarasikan macro dan tidak pernah menggunakannya dalam
kode, compiler akan mengabaikannya. Emu8086,unc merupakan salah satu contoh
bagaimana macro dapat dipakai, file ini berisi beberapa macro untuk mempermudah
pengkodean kita
Definisi Macro:
name MACRO [parameter …]
<instruction>
ENDM

Tidak seperti prosedur, macro harus didefenisikan diatas kode yan akan
memakainya, contoh:

MyMacro MACRO p1, p2, p3


MOV AX, p1
MOV BX, p2
MOV CX, p3
ENDM

ORG 100h
MyMacro 1, 2, 3
MyMacro 4, 5, DX
RET

Kode diatas diperluas menjadi:


MOV AX, 00001h
MOV BX, 00002h
MOV CX, 00003h
MOV AX, 00004h
MOV BX, 00005h
MOV CX, DX
52

Perbedaan macro dan prosedur:


- Prosedur dipakai dengan instruksi CALL, contoh;
CALL myProc
- Makro hanya menuliskan namanya saja, contoh:
MyMacro
- Prosedur terletak pada alamat yang spesifik di memori, dan jika kita
menggunakan prosedur yang sama sebanyak 100 kali, CPU hanya
mentransfer kendali ke bagian memori. Kendali akan dikembalikan dengan
instruksi RET. Stack yang digunakan untuk menyimpan alamat pengembalian.
Instruksi CALL memerlukan setidaknya 3 bytes, jadi ukuran output
executable filenya tida besar, tidak masalah seberapa banyak pemanggilan
prosedur dilakukan.
- Macro akan menambah secara langsung dalam kode program. Jadi jika kita
memakai 100 kali makrokompiler akan menambah sebanyak 100 kali pada
output exe filenya setiap kali macro tersebut dimasukkan.
- Stau atau general purpose register harus digunakan untuk mengirim
parameter dalam prosedur.
- Untuk mengirimkan parameter ke macro, kita dapat mengetiknya setelah
nama macronya, contoh:
MyMacro 1, 2, 3

- Untuk menandai akhir macro digunakan directive ENDM sudah cukup


- Untuk menandai akhir prosedur harus mengetikkan nama prosedur sebelum
directive ENDP.

Macro akan diperluas secara langsung dalam kode, sehingga jika ada label
didalam defenisi makro kita akan mendapatkan pesan error “duplicate
declaration” saat macro dipakai dua kali atau lebih. Untuk menghindari ini
digunakan directive LOCAL diikuti nama variabelnya, nama label atau prosedur,
contoh :

MyMacro2 MACRO
LOCAL label1, label2
CMP AX, 2
JE label1
53

CMP AX, 3
JE label2
label1:
INC AX
label2:
ADD AX, 2
ENDM

ORG 100h
MyMacro2
MyMacro2
RET

Jika kita akan merencanakan menggunakan macro pada program, mungkin


lebih baik menempatkan macro pada file yang berbeda. Tempatkan di folder Inc dan
gunakan directive INCLUDE file-name untuk menggunakan macro.
54

MODUL X
PENGENDALIAN PIRANTI EKSTERNAL

Ada 7 piranti yang dilampirkan pada emulator: traffic light, stepper – motor,
LED display, thermometer, printer, robot dan simple test. Kita dapat melihanya
dengan menklik menu “Virtual Devices” dari emulator. Secara umum, dimungkinkan
menggunakan CPU keluarga X86 untuk mengendalikan semua piranti. Perbedaannya
berada pada nomor Port I/O, ini dapat dimodifikasi menggunakan peralatan
elektronik. Biasanya file “.bin” dituliskan ke dalam chip Read Only Memory (ROM),
sistem membaca program dari chip, dan memuat ke RAM dan menjalankan sebagai
program. Prinsip ini digunakan untuk peralatan modern lainnya seperti micro-wave
oven dan lainnya.

Traffic Light

Biasanya untuk mengendalikan lampu lalu lintas, suatu array nilai digunakan. Nilai
dibaca dari array dan dikirim ke port, contohnya:
55

; controlling external device with 8086 microprosessor


; realistic test for C:\emu8086\device\Traffic_Lights.exe
#start = Traffic_Light.exe#

name “traffic”
MOV AX, all_red
OUT 4, AX
MOV SI, Offset situation

next:
MOV AX, [SI]
OUT 4, AX

; wait 5 seconds (5 million microsecons)


MOV CX, 4Ch ; 004C4B40h = 5000000
MOV DX, 4B40h
MOV AH, 86h
INT 15h

ADD SI, 2 ; next situation


CMP SI, sit_end
JB next
MOV SI, Offset situation
JMP next
; FEDC_BA98_7654_3210
situation dw 0000_0011_0000_1100b
S1 dw 0000_0110_1001_1010b
S2 dw 0000_1000_0110_0001b
S3 dw 0000_1000_0110_0001b
S4 dw 0000_0100_1101_0011b
all_red equ 0000_0010_0100_1001b
56

Motor Stepper

Motor dapat melangkah half step dengan memasang pasangan magnet, motor juga
dilangkahkan full step dengan memasang pasangan magnet, yang diikuti oleh
pasangan magnet yang lain dan pada akhirnya diikuti oleh magnet tunggal dan
seterusnya. Cara yang terbaik untuk membuat full step adalah membuat dua half
step.
Half step sama dengan 11.25’
Full ster sama dengan 22.5’
Motor dapat diputar baik secara searah jalum jam maupun berlawanan arah jarum
jam.

Robot

Untuk mengendalikan robot, algoritma yang komplek seharusnya bisa digunakan


untuk mendapatkn efisiensi maksimum. Cara sederhana yang tentu saja sangat tidak
efisien, adalah menggunakan algoritma random moving.
57

Anda mungkin juga menyukai