CHAPTER 8
CHAPTER 8
PROGRAMMING THE MICROPROCESSOR
Menggunakan program assembler MASM dan linker untuk membuat program yang berisi lebih dari satu modul.- Menjelaskan penggunaan EXTRN dan PUBLIC sebagaimana diterapkan pada pemrograman modular.
- Menyiapkan berkas pustaka yang berisi subrutin umum yang sering digunakan dan mempelajari cara menggunakan program DUMPBIN.
- Menulis dan menggunakan MACRO serta ENDM untuk mengembangkan urutan makro yang digunakan dalam pemrograman linear di modul yang terhubung dengan kode C++.
- Menunjukkan bagaimana berkas akses berurutan (sequential) dan acak (random) dikembangkan untuk digunakan dalam sebuah sistem.
- Mengembangkan program menggunakan penangan peristiwa (event handlers) untuk melakukan tugas keyboard dan tampilan.
- Menggunakan pernyataan bahasa assembly bersyarat dalam program.
- Menggunakan mouse dalam contoh program.
3. Modular Programming[Kembali]
Banyak program terlalu besar untuk dikembangkan oleh satu orang. Artinya, program biasanya dikembangkan oleh tim programmer. Program linker disediakan dalam Visual Studio sehingga modul-modul pemrograman dapat digabungkan menjadi sebuah program lengkap. Proses linking juga tersedia dari command prompt Windows. Bagian ini menjelaskan tentang linker, tugas linking, file library, serta EXTRN dan PUBLIC yang digunakan dalam modul program dan pemrograman modular.
The Assembler and Linker
Program assembler mengubah sebuah symbolic source module (file sumber) menjadi file objek heksadesimal. Assembler ini juga merupakan bagian dari Visual Studio, yang terdapat di folder C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\bin Kita sudah melihat banyak contoh file sumber simbolik yang ditulis dalam bahasa assembly di bab sebelumnya. Contoh 8–1 memperlihatkan dialog assembler ketika file sumber bernama NEW.ASM di-assemble. Dialog ini menggunakan assembler versi 6.15 di command line DOS. Versi yang tersedia di Visual C tidak dapat digunakan untuk program 16-bit DOS. Jika diperlukan assembler dan linker 16-bit, bisa diperoleh dalam Windows Driver Development Kit (DDK).mSetiap kali membuat file sumber, sebaiknya diberi ekstensi .ASM, meskipun tidak selalu memungkinkan (seperti sudah dibahas di bab sebelumnya). File sumber dapat dibuat menggunakan Notepad atau editor teks lain yang mampu menghasilkan file ASCII.
Untuk membuat program dengan ML (Macro Assembler), ketik perintah ML diikuti nama file sumber, misalnya ml new.asm.
-
/Fl: membuat file daftar (listing)
.LSTyang menampilkan hasil assemble dan kode mesin heksadesimal. Ini opsional tapi berguna untuk mengecek kesalahan. -
/c: hanya membuat file objek
.OBJtanpa langsung membuat file eksekusi.
Hasil assemble utama adalah file objek (.OBJ). File ini kemudian diproses oleh linker untuk digabung menjadi file eksekusi (.EXE) yang bisa dijalankan di DOS dengan mengetik namanya, misalnya FROG.
Jika program sangat kecil (kurang dari 64 KB), bisa dibuat sebagai file .COM, yang lebih cepat dijalankan dan ukurannya lebih kecil, tetapi hanya untuk DOS atau kebutuhan khusus seperti disimpan ke chip (EPROM/FLASH).
Setelah mengetik ML, linker akan meminta daftar object file yang dibuat assembler.
- Jika ada beberapa file, tulis program utama dulu (misalnya
NEW), lalu modul pendukung (WHAT,DONUT). - Untuk menambahkan library, tulis setelah perintah
/LINK, contoh: ML NEW.ASM /LINK NUMB.LIB
Di Windows, ML hanya bisa assemble, tidak bisa langsung link. Proses linking harus dilakukan lewat Visual Studio saat build. Bisa meng-assemble satu atau beberapa file untuk menghasilkan object file yang dipakai Visual C++.
Opsi penting:
-
/c : hanya kompilasi, hasilkan object file.
-
/Cx : pertahankan huruf besar/kecil pada nama.
-
/coff : buat object file format 32-bit.
Public and Extern
Directive PUBLIC dan EXTRN dipakai agar modul program bisa saling berkomunikasi.
-
PUBLIC: menandai label (alamat kode, data, atau segmen) supaya bisa dipakai modul lain.
-
EXTRN: memberi tahu bahwa label tersebut ada di modul lain.
Tanpa keduanya, modul mungkin bisa di-link, tapi tidak bisa saling mengakses. PUBLIC ditulis di bagian opcode untuk membuat label terlihat oleh modul lain. Jika segmen dibuat public, segmen dengan nama sama akan digabung otomatis.
Contoh 8–4 menunjukkan penggunaan pernyataan PUBLIC untuk mendefinisikan beberapa label agar dapat diakses modul lain dalam sebuah potongan program. Jika segmen dibuat publik, segmen tersebut akan digabung dengan segmen publik lain yang memiliki nama segmen sama.
Pernyataan EXTRN dapat muncul di segmen data maupun kode untuk menyatakan bahwa suatu label berada di luar segmen tersebut.
-
Jika data didefinisikan sebagai eksternal, ukurannya harus ditentukan sebagai BYTE, WORD, atau DWORD.
-
Jika alamat jump atau call bersifat eksternal, harus ditentukan sebagai NEAR atau FAR.
Contoh 8–5 menunjukkan bagaimana pernyataan EXTRN digunakan untuk menandai beberapa label yang berada di luar program yang ditampilkan.
Perhatikan pada contoh ini, setiap alamat atau data eksternal ditandai dengan huruf E pada listing heksadesimal hasil assemble. Diasumsikan bahwa Contoh 8–4 dan Contoh 8–5 di-link menjadi satu program.
Library file adalah kumpulan prosedur siap pakai untuk banyak program. Prosedur ini di-assemble dan compile menjadi satu file .LIB dengan program LIB (LIB.EXE) bawaan Visual Studio/MASM.
-
Saat proses link, hanya prosedur yang dibutuhkan program yang diambil dari library.
-
Memiliki library yang baik menghemat waktu karena fungsi umum tidak perlu ditulis ulang.
Cara membuat:
Gunakan perintah LIB untuk menggabungkan beberapa file .OBJ menjadi satu library.
Nama prosedur di dalamnya harus PUBLIC, dan variabel yang dipakai antarfile dideklarasikan dengan EXTRN. Contoh: modul berisi fungsi UpperCase dan LowerCase dijadikan library, lalu dapat dipanggil dari program C++ setelah file .LIB di-link ke program.
Contoh 8–7 memperlihatkan protokol C++ yang diperlukan untuk menggunakan fungsi dalam library tersebut di program C++, asalkan library telah di-*link* ke program.
Program LIB menampilkan pesan hak cipta Microsoft lalu meminta nama library.
Untuk membuat CASE.LIB, masukkan nama case. Karena file baru, LIB perlu diberi nama file objek. Sebelum itu, assemble dulu CASE.ASM dengan ML. Perintah lengkapnya (lihat Contoh 8–8) memanggil LIB diikuti nama file objek pada command line.
Program utilitas DUMPBIN.EXE disediakan untuk menampilkan isi library atau file lain. Contoh 8–9 menunjukkan hasil binary dump dengan opsi /all untuk menampilkan modul library CASE.LIB beserta seluruh komponennya. Di bagian atas daftar tersebut terlihat nama-nama publik untuk _UpperCase dan _LowerCase. Bagian Raw Data #1 berisi instruksi yang dikodekan dalam heksadesimal untuk kedua prosedur tersebut.
Saat file library di-link ke program, hanya prosedur yang dipakai yang masuk ke file eksekusi. Gunakan extern "C" di C++ untuk memanggil fungsi dari library. Di Visual C++ Express, pilih Create → Class Library untuk membuat DLL, yang bisa berisi kode C++ atau assembly. Untuk memakainya:
- Project → Add Reference, pilih file DLL.
Tambahkan #include di awal kode yang akan memakai DLL.
Makro adalah kumpulan instruksi untuk satu tugas, mirip prosedur tetapi tanpa CALL/RET. Saat dipanggil, instruksi makro langsung disisipkan ke program sehingga eksekusinya lebih cepat.
-
Tidak bisa dipakai di inline assembler, hanya di modul assembly eksternal.
-
Didefinisikan dengan MACRO dan diakhiri ENDM (tanpa label di depan ENDM).
-
Bisa punya parameter, contoh:
MOVE MACRO A,B.
Assembler akan mengekspansi makro ke instruksi lengkap saat assemble. Makro harus ditulis sebelum digunakan, biasanya di awal code segment.
Contoh 8–10 menunjukkan cara membuat dan menggunakan makro. Enam baris pertama mendefinisikan makro yang memindahkan isi memori berukuran word dari lokasi B ke lokasi A. Setelah didefinisikan, makro tersebut dipanggil dua kali.
Assembler akan mengekspansi makro ini, sehingga terlihat bagaimana instruksi perpindahan dibentuk. Setiap baris bahasa mesin heksadesimal yang diikuti angka (misalnya 1) adalah hasil ekspansi makro. Baris-barisan ini tidak diketik di program sumber; assembler yang menambahkannya (jika .LISTALL disertakan) untuk menunjukkan bahwa makro telah dimasukkan ke program.
Makro harus didefinisikan sebelum dipakai dalam program, sehingga biasanya ditulis di bagian awal code segment.
Makro bisa memiliki variabel lokal, yaitu variabel yang hanya berlaku di dalam makro. Gunakan direktif LOCAL untuk mendeklarasikannya, misalnya untuk alamat jump. Tanpa deklarasi lokal, pemakaian makro berulang akan menimbulkan error.
Perhatikan bagaimana label FILL1 diperlakukan saat makro diperluas: assembler membuat label yang diawali dengan
?? sebagai label yang dihasilkan secara otomatis.Makro FILL menyimpan sejumlah nilai 00H ke alamat memori tertentu. Label otomatis yang dibuat assembler diawali ??.
-
LOCAL harus ditulis tepat setelah perintah MACRO, bisa memuat hingga 35 label, agar tiap pemakaian makro punya label lokal sendiri.
Definisi makro bisa ditaruh di file terpisah (.INC atau .MAC) dan dimasukkan dengan INCLUDE, tanpa perlu PUBLIC atau EXTRN.
-
File include makro berfungsi seperti pustaka makro dan dapat dipakai bersama file library dalam satu program.
4. Using the Keyboard and Video Display[Kembali]
Saat ini, hampir tidak ada program yang tidak menggunakan keyboard dan layar video. Bagian ini menjelaskan cara menggunakan keyboard dan layar video yang terhubung ke IBM PC atau komputer kompatibel yang berjalan di bawah Windows.
Keyboard pada komputer personal dapat dibaca oleh berbagai objek yang tersedia di Visual C++. Data yang dibaca dari keyboard bisa berupa:
-
ASCII code (8-bit), atau
-
extended ASCII code.
Data ini kemudian disimpan dalam bentuk 8-bit ASCII atau 16-bit Unicode.
-
Unicode mengandung ASCII pada rentang
0000H–00FFH. -
Sisanya digunakan untuk karakter bahasa asing.
Catatan: Jangan gunakan
cinataugetchuntuk membaca tombol di Visual C++ (itu hanya berlaku pada aplikasi C++ berbasis DOS).
Sebagai gantinya, gunakan kontrol Visual C++ yang disediakan Windows.
Kode Scan Keyboard
-
Setiap tombol di keyboard memiliki scan code unik.
-
Beberapa tombol memiliki kode alternatif jika dikombinasikan dengan Shift, Ctrl, Alt.
-
Misalnya: tombol A memiliki kode
1Eh, tombol Enter =1Ch. -
Tabel 8–1 pada teks menunjukkan scan code dan extended ASCII untuk hampir semua tombol.
Untuk memahami cara membaca tombol di Windows, buat aplikasi sederhana:
-
Jalankan Visual C++ Express.
-
Pilih Create → Project.
-
Buat proyek CLR Windows Forms Application, beri nama, lalu klik OK.
Setelah form dibuat:
-
Tambahkan textbox control ke form (misalnya
textBox1). -
Agar kursor langsung berada di textbox saat aplikasi dibuka, gunakan perintah:
textBox1->Focus();→ letakkan di fungsi
Form1_Load.
Agar aplikasi dapat merespon penekanan tombol, gunakan event handler:
-
KeyDown → dipanggil saat tombol ditekan.
-
KeyPress → dipanggil setelah karakter dihasilkan.
Contoh Filtering Input
Misalnya, aplikasi hanya menerima angka 0–9 dan huruf A–F:
-
Jika huruf kecil ditekan, otomatis dikonversi ke huruf besar.
-
Tombol lain diabaikan.
Implementasi filtering:
-
Pada
KeyDown→ dicek apakah tombol valid (0–9, A–F, Backspace). -
Pada
KeyPress→ jika huruf kecil (a–f), ubah ke huruf besar (A–F). -
Hasil akhir → hanya angka 0–9 dan huruf A–F yang tampil di textbox.
Contoh filtering juga dapat dibuat dengan inline assembler.
-
Sebuah fungsi
Filtermengembalikan nilai true/false (1/0). -
Fungsi ini dipanggil dalam
KeyDownuntuk menentukan apakah tombol valid. -
Assembly digunakan untuk membandingkan kode ASCII dari tombol dengan rentang
0–9,A–F,a–f, atau Backspace.
Selain membaca input, program juga perlu menampilkan hasil di layar.
-
Textbox control dapat dipakai untuk menampilkan data.
-
Contoh: aplikasi dengan 2 textbox:
-
textBox1= input hex. -
textBox2= output hasil konversi ke desimal.
-
Proses:
-
User mengetik angka hex di
textBox1. -
Jika tombol Enter (ASCII 13) ditekan → program memproses input.
-
Fungsi
Convertsmengubah string hex ke integer. -
Hasil integer dikonversi ke string desimal (
Convert::ToString) → ditampilkan ditextBox2.
Konversi data diperlukan karena komputer bekerja dengan data biner, sementara manusia biasanya berinteraksi dalam bentuk angka desimal atau karakter ASCII.
-
Input dari keyboard → biasanya berupa kode ASCII.
-
Output ke layar → juga harus berupa ASCII.
-
Namun, perhitungan internal → dilakukan dalam bentuk biner/hexadecimal.
Karena itu, diperlukan konversi data di kedua arah.
Ada beberapa cara mengubah data biner menjadi karakter ASCII agar bisa ditampilkan:
1. Menggunakan Instruksi AAM
-
Instruksi AAM (ASCII Adjust after Multiply) membagi isi register AX dengan 10.
-
Hasil:
-
AH = digit puluhan (BCD).
-
AL = digit satuan (BCD).
-
-
Untuk mengubah ke ASCII: tambahkan
30Hpada masing-masing digit. -
Cocok untuk angka 0–99.
2. Menggunakan Pembagian Berulang
-
Untuk bilangan lebih besar, digunakan algoritma Horner atau pembagian berulang dengan 10.
-
Algoritma:
-
Bagi bilangan dengan 10.
-
Simpan sisa (remainder).
-
Ulangi pembagian hingga hasil = 0.
-
Ubah sisa-sisa pembagian ke karakter ASCII (
+30H) → susun dari belakang.
-
-
Contoh: angka 54321
-
54321 ÷ 10 = 5432 sisa 1 → ‘1’
-
5432 ÷ 10 = 543 sisa 2 → ‘2’
-
543 ÷ 10 = 54 sisa 3 → ‘3’
-
54 ÷ 10 = 5 sisa 4 → ‘4’
-
5 ÷ 10 = 0 sisa 5 → ‘5’
→ hasil ASCII ="54321".
-
3. Menggunakan Fungsi Convert::ToString() (di C++)
-
Dalam aplikasi Visual C++, cara paling sederhana adalah memanggil:
textBox2->Text = Convert::ToString(data); -
Fungsi ini otomatis mengubah bilangan biner ke string ASCII desimal.
Untuk membaca angka dari keyboard, data harus diubah dari ASCII ke biner.
Algoritma:
-
Mulai dari hasil = 0.
-
Untuk setiap digit ASCII:
-
Kurangi
30H→ dapatkan angka 0–9. -
Hasil sebelumnya × 10 + digit baru.
-
Contoh: "2316"
-
‘2’ → 2 → (0×10)+2 = 2
-
‘3’ → 3 → (2×10)+3 = 23
-
‘1’ → 1 → (23×10)+1 = 231
-
‘6’ → 6 → (231×10)+6 = 2316
Selain konversi biner–desimal, sering juga dibutuhkan konversi antara ASCII ↔ hex.
1. Membaca Hex dari Keyboard
-
Jika input =
0–9→ kurangi30H. -
Jika input =
A–F→ kurangi37H. -
Jika input =
a–f→ kurangi57H.
Contoh:
-
‘9’ → 39H – 30H = 09H.
-
‘B’ → 42H – 37H = 0BH.
-
‘d’ → 64H – 57H = 0DH.
2. Menampilkan Hex ke Layar
-
Ambil nibble (4 bit) dari angka biner.
-
Jika nilainya 0–9 → tambahkan
30H. -
Jika nilainya 10–15 → tambahkan
37H. -
Gabungkan tiap nibble untuk membuat string heksadesimal.
Contoh: bilangan 2AB4H → tampil sebagai "2AB4".
Seringkali konversi lebih mudah jika menggunakan lookup table. Contoh: BCD → Seven-Segment Display
-
Lookup table berisi pola untuk tiap angka 0–9.
-
Misalnya (untuk common cathode):
0 → 3FH (0111111) 1 → 06H (0000110) 2 → 5BH (1011011) 3 → 4FH (1001111) 4 → 66H (1100110) 5 → 6DH (1101101) 6 → 7DH (1111101) 7 → 07H (0000111) 8 → 7FH (1111111) 9 → 6FH (1101111) -
Program cukup mengambil nilai dari tabel dengan instruksi XLAT.
Lookup table juga bisa dipakai untuk konversi lain, misalnya angka → teks (0 = “Sunday”, 1 = “Monday”, dst).
-
Konversi data sangat penting agar komputer (biner) dapat berkomunikasi dengan manusia (desimal/ASCII).
-
Binary → ASCII → pakai AAM, pembagian berulang, atau fungsi
Convert::ToString. -
ASCII → Binary → pakai metode string to integer (×10 + digit).
-
ASCII ↔ Hexadecimal → langsung pakai manipulasi kode ASCII.
-
Lookup table → metode efisien untuk konversi cepat (misalnya seven-segment).
Banyak program memerlukan penyimpanan data permanen di dalam file disk. Data bisa berupa teks, angka, atau bentuk lain, yang harus dibaca dan ditulis kembali saat program dijalankan. Ada dua cara utama untuk mengakses file:
-
Sequential file (berurutan)
-
Data dibaca/ditulis mulai dari awal file sampai akhir.
-
Sama seperti membaca kaset atau tape, hanya bisa bergerak maju.
-
-
Random access file (acak)
-
Data dalam file dapat langsung diakses di lokasi tertentu.
-
Berguna untuk database atau aplikasi yang membutuhkan akses cepat ke bagian tertentu dari file.
-
Sequential Files
A. Definisi
File berurutan adalah file yang hanya dapat diakses mulai dari awal ke akhir. Jika ingin membaca data di tengah, program harus tetap membaca semua data sebelumnya.
B. Cara Kerja
-
Saat membuka file untuk dibaca, pointer file berada di awal.
-
Data dibaca satu per satu sampai akhir file.
-
Saat membuka file untuk ditulis, data bisa:
-
Menimpa file lama (overwrite).
-
Ditambahkan di akhir file (append).
-
C. Kegunaan
-
Menyimpan laporan, data teks, daftar nama, atau log sistem.
-
Cocok untuk aplikasi di mana data selalu diproses secara berurutan.
D. Implementasi (C++ / .NET)
-
StreamReader dan StreamWriter digunakan untuk sequential file.
-
Contoh:
StreamWriter^ outFile = gcnew StreamWriter("data.txt"); outFile->WriteLine("Halo Dunia"); outFile->Close(); StreamReader^ inFile = gcnew StreamReader("data.txt"); String^ teks = inFile->ReadLine(); inFile->Close();
Random Access Files
A. Definisi
File akses acak memungkinkan program untuk langsung melompat ke posisi tertentu dalam file tanpa harus membaca dari awal.
B. Cara Kerja
-
File dibagi menjadi record dengan ukuran tetap (misalnya 128 byte per record).
-
Lokasi record dihitung dengan rumus offset:
Offset = (NomorRecord – 1) × UkuranRecord -
Dengan fungsi
seek(C) atauFileStream::Seek(.NET), pointer file dapat dipindahkan langsung ke byte tertentu.
C. Kegunaan
-
Cocok untuk database sederhana, sistem inventori, atau aplikasi perpustakaan, di mana data tertentu sering diakses atau diperbarui.
D. Implementasi (C / .NET)
-
C menggunakan
fseekdanftell. -
.NET menggunakan
FileStream. -
Contoh C++/CLI:
FileStream^ file = gcnew FileStream("data.bin", FileMode::OpenOrCreate); array<Byte>^ buffer = gcnew array<Byte>(128); // 1 record = 128 byte // Pindah ke record ke-3 file->Seek(2 * 128, SeekOrigin::Begin); // Tulis record Encoding^ enc = Encoding::ASCII; buffer = enc->GetBytes("Data record ke-3"); file->Write(buffer, 0, buffer->Length); file->Close();
-
Sequential file → sederhana, digunakan untuk data yang dibaca/ditulis dari awal hingga akhir.
-
Random access file → lebih fleksibel, digunakan untuk database atau data dengan ukuran record tetap.
-
Pemilihan metode tergantung pada jenis aplikasi:
-
Jika data selalu diproses urut → sequential.
-
Jika butuh akses langsung dan sering update → random access.
-
Tujuan
Membuat aplikasi Windows (Visual C++ Express) yang menampilkan angka 0–9 pada sebuah tampilan seven-segment. Angka ditampilkan berdasarkan tombol angka yang ditekan pada keyboard.
Komponen Program
-
Input Keyboard
-
Program hanya menerima input dari tombol angka 0–9.
-
Input selain angka ditolak melalui event handler (
KeyDowndanKeyPress).
-
-
Lookup Table
-
Sebuah tabel pencarian digunakan untuk mengonversi angka yang ditekan ke dalam pola seven-segment.
-
Setiap angka (0–9) memiliki pola unik yang menunjukkan segmen mana yang harus dinyalakan.
-
Contoh pola (untuk common cathode, aktif tinggi):
0 → 0x3F (0111111) 1 → 0x06 (0000110) 2 → 0x5B (1011011) 3 → 0x4F (1001111) 4 → 0x66 (1100110) 5 → 0x6D (1101101) 6 → 0x7D (1111101) 7 → 0x07 (0000111) 8 → 0x7F (1111111) 9 → 0x6F (1101111)
-
-
Kontrol Panel (untuk segmen)
-
Tampilan seven-segment dibuat dari panel-panel persegi panjang.
-
Segmen horizontal: berukuran sekitar 120×25 piksel.
-
Segmen vertikal: berukuran sekitar 25×75 piksel.
-
Setiap panel mewakili satu segmen (a–g).
-
-
Warna Segmen
-
Jika segmen aktif, panel diwarnai merah.
-
Jika segmen mati, panel diwarnai hitam.
-
Alur Kerja Program
-
User menekan tombol angka (
0–9) pada keyboard. -
Program memeriksa input:
-
Jika valid (0–9) → diterima.
-
Jika tidak valid → diabaikan.
-
-
Angka yang valid digunakan sebagai indeks untuk lookup table.
-
Lookup table memberikan pola biner yang menentukan segmen mana yang aktif.
-
Program menyalakan/mematikan panel-panel sesuai pola.
-
Angka muncul di layar dalam bentuk seven-segment digital.
Hasil Program
-
Jika user mengetik
5, lookup table memberikan pola0x6D. -
Segmen yang sesuai pola tersebut menyala (misalnya a, f, g, c, d).
-
Panel-panel berwarna merah membentuk angka
5di layar.