Hubungkan komponen sesuai rangkaian. Klik Play untuk simulasi.
6
Untuk 8255, atur Control Word melalui switch lalu amati output di LED.
Tips
•Di lab kampus Proteus sudah terinstal dengan library lengkap.
•Gunakan fitur Terminal di Proteus untuk simulasi serial.
•Jika komponen 8086 tidak ditemukan, cari dengan kata kunci "8086" tanpa "Intel".
Lembar Kerja Praktikum (LKP)
Tujuan
▸Menggunakan instruksi MOV dengan berbagai kombinasi operand (register ↔ register, register ↔ memori, immediate → register).
▸Memahami batasan instruksi MOV: tidak bisa memori-ke-memori, tidak bisa segmen-ke-segmen langsung.
▸Menggunakan PUSH dan POP untuk menyimpan dan mengambil data dari stack, memahami mekanisme LIFO.
▸Menggunakan XCHG untuk pertukaran data tanpa register sementara.
▸Menggunakan LEA untuk memuat alamat efektif variabel ke register (bukan isinya).
Teori Singkat
Instruksi MOV adalah instruksi transfer data paling dasar pada 8086. Format umumnya: MOV destinasi, sumber. Aturan penting: (1) ukuran operand harus sama (8-bit ke 8-bit, 16-bit ke 16-bit), (2) tidak bisa MOV langsung dari memori ke memori — harus lewat register perantara, (3) CS tidak boleh menjadi destinasi. Stack beroperasi dengan prinsip LIFO (Last In First Out), bertumbuh ke alamat lebih rendah, dan SP selalu menunjuk ke TOP of stack. LEA (Load Effective Address) menghitung offset alamat dan menyimpannya ke register, berbeda dengan MOV yang mengambil isi dari alamat tersebut.
Langkah Kerja
Buka emu8086, pilih New → Empty Workspace.
Tulis kode dasar: MOV AX, 1111H dan MOV BX, 2222H. Klik Emulate, jalankan Single Step. Amati register AX dan BX berubah.
Tambahkan MOV CX, AX → amati CX menjadi 1111H. Ini contoh register-ke-register.
Di bagian .data, definisikan bil1 DW 1234H dan bil2 DW 5678H. Tulis MOV AX, bil1 dan MOV BX, bil2. Amati tab Memory — cari alamat DS:0000 dan DS:0002.
Coba tukar isi bil1 dan bil2: MOV AX, bil1; MOV BX, bil2; MOV bil1, BX; MOV bil2, AX. Lihat memori sebelum dan sesudah — buktikan berhasil.
Buat program PUSH/POP: MOV AX, 1111H; PUSH AX; MOV AX, 9999H; POP AX. Amati SP berubah saat PUSH (berkurang 2) dan POP (bertambah 2), serta AX kembali ke 1111H.
Gunakan XCHG: MOV AX, 1111H; MOV BX, 2222H; XCHG AX, BX. Amati kedua register bertukar isi dalam satu instruksi.
Definisikan variabel arr DW 10, 20, 30. Gunakan LEA SI, arr lalu MOV AX, [SI]. Bandingkan hasilnya jika menggunakan MOV SI, arr — bedakan nilai alamat vs isi memori.
Tugas Praktikum
Buat program yang: (a) mendeklarasikan 4 variabel 16-bit (A, B, C, D), (b) menukar isi A↔B dan C↔D menggunakan XCHG, (c) lalu tukar lagi A↔C dan B↔D menggunakan MOV lewat register sementara. Tampilkan isi ke-4 variabel di memori setelah setiap tahap pertukaran. Screenshot kondisi memori di 3 titik: awal, setelah XCHG, setelah MOV.
Tujuan
▸Menggunakan instruksi ADD dan SUB untuk penjumlahan dan pengurangan bilangan 8-bit maupun 16-bit.
▸Memahami pengaruh operasi aritmatika terhadap flag register: CF (Carry/Borrow), ZF (Zero), SF (Sign), OF (Overflow).
▸Menggunakan MUL untuk perkalian unsigned dan IMUL untuk perkalian signed.
▸Menggunakan DIV untuk pembagian unsigned dan IDIV untuk pembagian signed.
▸Menggunakan instruksi INC, DEC, dan NEG beserta efeknya terhadap flag.
Teori Singkat
ADD dan SUB mengubah semua flag aritmatika. CF di-set jika ada carry-out (penjumlahan) atau borrow (pengurangan) dari bit tertinggi. OF di-set jika hasil melampaui rentang signed (positif→negatif atau sebaliknya). MUL operand: jika operand 8-bit, hasil 16-bit di AX; jika operand 16-bit, hasil 32-bit di DX:AX. DIV operand: jika operand 8-bit, DX:AX dibagi operand, kuota di AL, sisa di AH; jika operand 16-bit, DX:AX dibagi operand, kuota di AX, sisa di DX. CWD (Convert Word to Doubleword) menandai-extend AX ke DX:AX — penting sebelum DIV 16-bit.
Langkah Kerja
Definisikan a DW 25 dan b DW 7. Buat program penjumlahan: MOV AX, a; ADD AX, b; MOV hasil, AX. Jalankan, cek hasil = 32 (0020H) di memori.
Amati register Flags setelah ADD. Catat nilai CF, ZF, SF, OF. Sekarang ganti b = 65535 (FFFFH). Jumlahkan lagi — CF harus = 1 (carry terjadi).
Buat program pengurangan: MOV AX, a; SUB AX, b. Dengan a=25, b=7, hasil = 18. Amati CF = 0. Ganti a=7, b=25 — CF harus = 1 (borrow).
Buat perkalian 8-bit: MOV AL, 25; MOV BL, 7; MUL BL. Hasil di AX = 175 (00AFH). Perhatikan AH = 00 (high byte), AL = AF (low byte).
Buat perkalian 16-bit: MOV AX, 1000; MOV BX, 50; MUL BX. Hasil 50000 = C350H. DX = 0000H, AX = C350H. Amati kedua register.
Coba operasi dengan bilangan negatif: MOV AX, -5; MOV BX, 3; ADD AX, BX. Hasil = -2 = FFFEH. Amati SF = 1 (menandakan negatif).
Gunakan INC dan DEC: MOV CX, 0; DEC CX. CX menjadi FFFFH (underflow). Amati ZF = 0, SF = 1. Sekarang INC CX → CX = 0000H, ZF = 1.
Tugas Praktikum
Buat "kalkulator 4 operasi": input dua bilangan 16-bit (A dan B) sebagai variabel .data. Hitung JUMBLAH (A+B), KURANG (A−B), KALI (A×B), dan BAGI (A/B, ambil kuota saja). Simpan keempat hasil di 4 variabel terpisah. Gunakan MUL 16-bit (hasil di DX:AX, simpan AX saja) dan DIV 16-bit dengan CWD. Screenshot tabel memori yang menunjukkan semua 6 variabel (A, B, dan 4 hasil). Uji dengan A=300, B=12.
Tujuan
▸Mendeklarasikan dan mengakses elemen array 16-bit menggunakan register indeks (SI/BX/DI).
▸Mengimplementasikan percabangan dengan CMP + conditional jump (JG, JL, JGE, JLE, JE, JNE).
▸Menggunakan instruksi LOOP untuk iterasi berdasar counter CX.
▸Menghitung akumulasi (running sum) dan menerapkan pembagian untuk rata-rata.
▸Memahami penggunaan direktif EQU dan operator aritmatika assembler ($-arr)/2 untuk menghitung jumlah elemen.
Teori Singkat
Array di Assembly hanyalah blok memori berturutan. Untuk array DW (word), setiap elemen menempati 2 byte, sehingga indeks berikutnya diakses dengan menambah 2 ke register pointer. Instruksi CMP melakukan pengurangan implisit (operand1 − operand2) tanpa menyimpan hasil, tetapi mengubah flag. JG/JL bekerja untuk signed (memperhatikan SF dan OF), JAE/JBE untuk unsigned (hanya CF dan ZF). LOOP mendekremen CX secara otomatis dan lompat jika CX ≠ 0, menggantikan kombinasi DEC CX + JNZ. Operator $ dalam assembler merujuk ke counter lokasi saat ini, sehingga ($-arr)/2 menghitung jumlah elemen word.
Langkah Kerja
Definisikan array: arr DW 25, 78, 13, 92, 45, 67, 31 dan n EQU ($-arr)/2. Variabel: maks DW 0, min DW 0, jum DW 0, rata DW 0.
Inisialisasi pointer: LEA SI, arr. Inisialisasi counter: MOV CX, n. Muat elemen pertama sebagai nilai awal: MOV AX, [SI]; MOV maks, AX; MOV min, AX.
Inisialisasi akumulasi: MOV jum, 0. Decrement CX (karena elemen pertama sudah diproses): DEC CX; ADD SI, 2.
Buat label loop ulangi:. Muat elemen berikutnya: MOV AX, [SI]. Tambahkan ke akumulasi: ADD jum, AX.
Pindah ke elemen berikutnya dan ulangi: ADD SI, 2; LOOP ulangi.
Setelah loop, hitung rata-rata: MOV AX, jum; MOV BX, n; CWD; DIV BX; MOV rata, AX.
Jalankan program dengan Single Step. Periksa memori: maks harus = 92 (005CH), min = 13 (000DH), jum = 351, rata = 50 (sisa pembulatan).
Tugas Praktikum
Ubah program untuk array 10 elemen: arr DW 150, 23, 487, 62, 331, 8, 295, 174, 56, 210. Hitung maks, min, jumlah, dan rata-rata. Tambahkan fitur: hitung juga berapa banyak elemen yang nilainya di atas rata-rata (simpan di variabel "cntAbove"). Screenshot seluruh blok memori yang berisi array dan semua variabel hasil.
Tujuan
▸Membuat prosedur dengan instruksi CALL dan RET, memahami mekanisme stack saat pemanggilan.
▸Mengimplementasikan algoritma konversi bilangan heksadesimal → string desimal dengan pembagian berulang.
▸Mengimplementasikan algoritma konversi bilangan desimal → string heksadesimal dengan shift dan mask.
▸Membuat prosedur utilitas PRINT_STRING untuk menampilkan string yang diakhiri "$" menggunakan INT 21H.
Teori Singkat
CALL mendorong (push) alamat instruksi berikutnya ke stack, lalu lompat ke label prosedur. RET mengambil (pop) alamat tersebut dari stack sehingga eksekusi kembali ke pemanggil. Karena 8086 tidak memiliki mekanisme parameter formal, konvensi yang umum adalah: kirim parameter via register (AX, BX, CX, DX), kembalikan hasil via AX. Algoritma konversi hex→dec: bagi nilai dengan 10 berulang kali, simpan sisa (digit) ke stack, lalu pop satu per satu dan konversi ke ASCII (+30H). Stack digunakan karena digit dihasilkan dari digit paling tidak signifikan (satuan) terlebih dahulu, tapi harus ditampilkan dari yang paling signifikan (ribuan).
Langkah Kerja
Buat struktur dasar: .model small .stack 100h .data .code. Definisikan buffer output: buf DB 6 DUP(0), "$" (cukup untuk angka 65535 + "$").
Buat prosedur PRINT_STRING: PUSH DX; MOV AH, 09H; INT 21H; POP DX; RET. Parameter: DX = alamat string.
Buat prosedur HEX_TO_DEC. Parameter masuk: AX = nilai 16-bit. Parameter keluar: BX = alamat buffer berisi string desimal + "$".
Di dalam HEX_TO_DEC: inisialisasi CX=0 (penghitung digit). Loop: MOV DX, 0; MOV BX, 10; DIV BX (AX=kuota, DX=sisa). Tambah 30H ke DL (konversi ke ASCII). PUSH DX. INC CX. Ulangi sampai AX=0.
Setelah loop, ambil digit dari stack ke buffer: POP DX; MOV [BX], DL; INC BX; LOOP pop_loop. Tambahkan "$" di akhir: MOV BYTE PTR [BX], "$".
Di program utama, panggil untuk beberapa nilai: MOV AX, 0; LEA BX, buf; CALL HEX_TO_DEC; LEA DX, buf; CALL PRINT_STRING.
Tambahkan newline antar output: LEA DX, newline; CALL PRINT_STRING di mana newline DB 0DH, 0AH, "$".
Buat prosedur DEC_TO_HEX: parameter AX = nilai desimal (0-65535). Algoritma: rotasi AX ke kiri 4 bit, AND dengan 0FH untuk ambil nibble, konversi ke ASCII (jika >9 tambah 7H untuk A-F). Simpan ke buffer BX. Ulangi 4 kali untuk 4 digit heksa.
Di program utama, tampilkan: "255 desimal = FF heksa", "4096 desimal = 1000 heksa", dan "65535 desimal = FFFF heksa". Gunakan kedua prosedur.
Tugas Praktikum
Buat program dengan 3 prosedur: (1) HEX_TO_DEC, (2) DEC_TO_HEX, (3) PRINT_STRING. Program utama mendeklarasikan 3 variabel: val1=100, val2=255, val3=65535. Untuk setiap nilai, tampilkan dalam format: "XXXX (desimal) = XXXX (heksa)". Contoh output: "0100 (desimal) = 0064 (heksa)". Gunakan prosedur padding jika perlu agar selalu 5 digit desimal dan 4 digit heksa.
Tujuan
▸Memahami pengalamatan string DS:SI (source) dan ES:DI (destination) pada arsitektur 8086.
▸Menggunakan instruksi string MOVSB dengan prefix REP untuk menyalin blok string.
▸Menggunakan CMPSB dengan prefix REPE/REPZ untuk membandingkan dua string.
▸Menggunakan SCASB dengan prefix REPNE/REPNZ untuk mencari karakter dalam string.
▸Mengontrol arah pengulangan dengan instruksi CLD (clear direction, maju) dan STD (set direction, mundur).
▸Mengimplementasikan pembalikan string secara manual tanpa instruksi string bawaan.
Teori Singkat
Instruksi string pada 8086 (MOVSB, CMPSB, SCASB, STOSB, LODSB) secara implisit menggunakan register DS:SI sebagai sumber dan ES:DI sebagai tujuan, serta mendekremen/inkremen keduanya setelah eksekusi berdasarkan flag Direction (DF). CLD membuat DF=0 (SI/DI bertambah → arah maju), STD membuat DF=1 (SI/DI berkurang → arah mundur). Prefix REP mengulangi instruksi CX kali. REPE/REPZ berhenti lebih awal jika ZF=0 (tidak sama). REPNE/REPNZ berhenti lebih awal jika ZF=1 (sudah sama). CX selalu didekremen setiap iterasi.
Langkah Kerja
Definisikan: src DB "Hello World$", dst DB 12 DUP(0). Pastikan buffer dst cukup besar.
Salin string: MOV AX, @data; MOV DS, AX; MOV ES, AX; CLD; LEA SI, src; LEA DI, dst; MOV CX, 11; REP MOVSB. Tambahkan "$" di akhir dst: MOV BYTE PTR [DI], "$". Tampilkan dst dengan INT 21H AH=09H.
Definisikan string kedua: str2 DB "Hello World$". Bandingkan: CLD; LEA SI, src; LEA DI, str2; MOV CX, 11; REPE CMPSB. Setelah REPE, periksa ZF: jika ZF=1 → sama, ZF=0 → berbeda di posisi tertentu. Tampilkan pesan hasil.
Ganti str2 menjadi "Hello WorldX" dan ulangi perbandingan. ZF harus = 0. Hitung posisi perbedaan: SUB DI, (offset str2); DEC DI — DI sekarang berisi indeks karakter pertama yang berbeda.
Cari karakter: CLD; LEA DI, src; MOV AL, "W"; MOV CX, 11; REPNE SCASB. Jika ZF=1 setelah REPNE, karakter ditemukan. Hitung posisi: SUB DI, (offset src); DEC DI.
Coba cari karakter yang tidak ada (misalnya "Z"). ZF harus = 0. Tampilkan pesan "Karakter tidak ditemukan".
Implementasikan pembalikan string manual tanpa instruksi string: hitung panjang string (cari "$" dengan loop), lalu tukar karakter pertama dengan terakhir, kedua dengan kedua terakhir, dst. Gunakan register sebagai penunjuk kiri dan kanan.
Tampilkan string asli dan string yang sudah dibalik. Contoh: "Hello World" → "dlroW olleH".
Tugas Praktikum
Buat program yang: (1) mendefinisikan string "Mikroprosesor", (2) menyalinnya ke buffer lain, (3) membalik string asli secara in-place (tanpa buffer tambahan), (4) membandingkan string asli (sebelum dibalik) dengan string salinan — harus "berbeda", (5) mencari huruf "r" dalam string asli dan melaporkan posisinya. Tampilkan semua hasil dengan pesan yang jelas menggunakan INT 21H.
Tujuan
▸Membaca satu karakter dari keyboard menggunakan INT 21H AH=01H dan memahami echo otomatis.
▸Membaca string dari keyboard menggunakan INT 21H AH=0AH dan memahami format buffer DTA (Data Transfer Area).
▸Menampilkan string ke layar menggunakan INT 21H AH=09H (string berakhiran "$") dan AH=02H (satu karakter via DL).
▸Membuat program menu berulang dengan validasi input dan penanganan pilihan salah.
▸Mengkonversi input string ASCII menjadi nilai numerik untuk pemrosesan aritmatika.
Teori Singkat
INT 21H menyediakan berbagai fungsi DOS. AH=01H membaca 1 karakter, menyimpannya di AL, dan menampilkannya (echo). AH=0AH membaca string hingga Enter ditekan. Buffer untuk AH=0AH harus memiliki format khusus: byte ke-0 = panjang maksimum (termasuk CR), byte ke-1 = diisi DOS dengan jumlah karakter aktual (tanpa CR), byte ke-2 onwards = karakter yang diketik. AH=09H menampilkan string di DS:DX yang diakhiri "$". AH=02H menampilkan 1 karakter di DL. AH=4CH mengakhiri program dan kembali ke DOS.
Langkah Kerja
Definisikan pesan-pesan: menu DB 0DH,0AH,"=== KALKULATOR ===",0DH,0AH,"1. Jumlah",0DH,0AH,"2. Kurang",0DH,0AH,"3. Keluar",0DH,0AH,"Pilih: $"
Tampilkan menu: LEA DX, menu; MOV AH, 09H; INT 21H.
Baca pilihan: MOV AH, 01H; INT 21H; MOV BL, AL. BL sekarang berisi karakter ASCII "1", "2", atau "3".
Bandingkan pilihan: CMP BL, "1"; JE pilih_jumlah; CMP BL, "2"; JE pilih_kurang; CMP BL, "3"; JE keluar; JMP salah_pilihan.
Untuk setiap pilihan yang valid, tampilkan sub-menu untuk memasukkan dua angka. Definisikan buffer input: buf DB 5, 0, 5 DUP(0) (maks 4 digit + CR).
Tampilkan prompt "Angka 1: ", baca dengan AH=0AH ke buf. Konversi string di buf+2 menjadi angka: loop mulai dari buf+1 (panjang aktual), ambil setiap karakter, kurangi 30H, kalikan akumulasi dengan 10, tambah digit baru.
Ulangi untuk Angka 2. Simpan kedua nilai di variabel num1 dan num2. Lakukan operasi (ADD atau SUB). Konversi hasil kembali ke string ASCII dan tampilkan.
Buat label salah_pilihan: yang menampilkan "Pilihan tidak valid!" lalu lompat kembali ke tampilan menu. Buat loop utama agar program terus berjalan sampai pilihan 3 dipilih.
Untuk konversi hasil ke ASCII: bagi dengan 10 berulang kali, simpan sisa+30H ke stack, pop dan simpan ke buffer, tambah "$" di akhir.
Tugas Praktikum
Buat kalkulator interaktif lengkap dengan menu: 1=Jumlah, 2=Kurang, 3=Kali, 4=Bagi, 5=Keluar. Program harus: (a) menampilkan menu, (b) membaca pilihan dan memvalidasi (jika salah, tampilkan error dan ulangi), (c) untuk operasi yang dipilih, minta input 2 angka (masing-masing sampai 4 digit), (d) hitung dan tampilkan hasil dalam format "25 + 7 = 32", (e) loop kembali ke menu setelah menampilkan hasil. Gunakan prosedur terpisah untuk: baca_angka (input→register), tampilkan_angka (register→output), dan tampilkan_hasil.
Tujuan
▸Memahami arsitektur internal 8255A: 3 port I/O 8-bit (A, B, C) dan 1 register Control Word.
▸Merancang rangkaian 8086 + 8255A di Proteus ISIS dengan konfigurasi I/O yang benar.
▸Memprogram Control Word Register (CWR) untuk mengatur mode operasi dan arah setiap port.
▸Mengirim data ke port output untuk mengendalikan LED (all-on, all-off, running LED, blinking).
▸Membaca data dari port input (switch) dan menampilkannya ke port output (LED).
Teori Singkat
8255A memiliki 4 register port yang diakses melalui A0 dan A1: 00=Port A, 01=Port B, 10=Port C, 11=Control Word Register. Dalam konfigurasi minimum 8086, alamat port-nya: 60H (A), 61H (B), 62H (C), 63H (CWR). Control Word untuk Mode 0 (I/O dasar): bit 7=1 (mode set flag), bit 6-5=00 (Mode 0), bit 4=arah Port C upper (0=output, 1=input), bit 3=arah Port C lower (0=output, 1=input), bit 2=arah Port B (0=output, 1=input), bit 1=arah Port A (0=output, 1=input), bit 0=0 (Mode 0 untuk grup B). Contoh: 80H = Mode 0, semua port output. 82H = Mode 0, Port A input, lainnya output. 90H = Mode 0, Port B input, lainnya output.
Langkah Kerja
Di Proteus, buat project baru. Tambahkan komponen: 8086 (prosesor), 8255A (PPI), 8 buah LED (aktif low, tambahkan resistor pull-up atau gunakan LOGICSTATE yang di-invert), dan 8 buah switch (LOGICSTATE).
Hubungkan bus data 8086 (D0-D7) ke 8255A (D0-D7). Hubungkan address lines: A0 8086 → A0 8255, A1 8086 → A1 8255. Hubungkan RD dan WR. Hubungkan CS 8255 ke decoder atau ground (aktif low, selalu terpilih jika tidak ada decoder).
Hubungkan Port A 8255 (PA0-PA7) ke 8 LED. Hubungkan Port B 8255 (PB0-PB7) ke 8 switch (LOGICSTATE).
Tulis program: inisialisasi 8255 dengan Control Word 80H (Mode 0, semua output) untuk pengujian LED dulu: MOV DX, 63H; MOV AL, 80H; OUT DX, AL.
Tes all-on: MOV DX, 60H; MOV AL, 0FFH; OUT DX, AL. Semua LED menyala. Tes all-off: MOV AL, 00H; OUT DX, AL. Semua LED mati.
Buat running LED: definisikan tabel pola pola DW 01H, 02H, 04H, 08H, 10H, 20H, 40H, 80H. Loop: ambil pola dari tabel, kirim ke Port A, delay, pola berikutnya. Ulangi terus-menerus.
Buat blinking LED: kirim FFH, delay, kirim 00H, delay, ulangi. Atau buat pola bergantian: AAH (10101010) dan 55H (01010101).
Ubah Control Word menjadi 82H (Port A = input, Port B = output) — atau 90H (Port A = output, Port B = input) sesuai rangkaian. Baca switch dari Port B: MOV DX, 61H; IN AL, DX. Kirim ke LED di Port A: MOV DX, 60H; OUT DX, AL. Loop terus sehingga perubahan switch langsung terlihat di LED.
Amati di Proteus: ubah-ubah posisi switch, verifikasi LED menyala sesuai pola bit switch.
Tugas Praktikum
Rancang rangkaian di Proteus dengan spesifikasi: Port A = 8 LED (output), Port B = 8 switch (input), Port C lower = 1 LED tambahan (output) sebagai indikator. Program harus: (a) baca switch dari Port B, (b) tampilkan ke LED Port A, (c) jika switch 0 (bit 0) = ON, jalankan mode running LED di Port A (abaikan switch lain), (d) jika switch 0 = OFF, Port A mencerminkan Port B langsung, (e) LED indikator di PC0 menyala hanya saat mode running LED aktif. Screenshot rangkaian dan tunjukkan 2 kondisi: mode normal dan mode running LED.
Tujuan
▸Memahami arsitektur internal 8253: 3 counter 16-bit independen, masing-masing dengan register control word sendiri.
▸Merancang rangkaian 8086 + 8253 di Proteus dan menghubungkan sinyal clock input serta output.
▸Memprogram Control Word Register 8253 untuk mengatur mode operasi, jenis akses baca/tulis, dan pemilihan counter.
▸Menghitung nilai count yang dibutuhkan untuk menghasilkan frekuensi output tertentu (Mode 3: square wave).
▸Mengamati dan mengukur sinyal output menggunakan osiloskop virtual di Proteus.
Teori Singkat
8253 memiliki 3 counter identik (Counter 0, 1, 2), masing-masing 16-bit. Alamat port: 40H (Counter 0), 41H (Counter 1), 42H (Counter 2), 43H (Control Word Register). Format Control Word: bit 7-6 = nomor counter (00=C0, 01=C1, 10=C2), bit 5-4 = jenis read/write (00=latch, 01=low byte only, 10=high byte only, 11=low lalu high), bit 3-1 = mode operasi (000=Mode 0, 011=Mode 3, dll), bit 0 = 0=binary, 1=BCD. Mode 3 (Square Wave Generator): output berganti tinggi-rendah setiap setenguh periode count, menghasilkan gelombang kotak simetris. Rumus: f_out = f_in / count. Jika count genap, duty cycle tepat 50%. Jika count ganjil, high lebih lama 1 clock dari low.
Langkah Kerja
Di Proteus, buat project baru. Tambahkan: 8086, 8253, source clock (gunakan DCLOCK atau CLOCK pada frekuensi 1 MHz), dan 3 osiloskop virtual (dari panel Instruments).
Hubungkan bus data 8086 ke 8253. Hubungkan A0, A1 untuk seleksi register. Hubungkan RD, WR, CS. Hubungkan CLK0 ke clock 1 MHz. Hubungkan OUT0 ke osiloskop Channel A.
Tulis kode: MOV DX, 43H; MOV AL, 36H; OUT DX, AL (kirim CWR). MOV DX, 40H; MOV AX, 03E8H; OUT DX, AL; MOV AL, AH; OUT DX, AL (kirim low byte dulu, lalu high byte).
Jalankan simulasi Proteus. Buka osiloskop, atur timebase hingga bisa melihat beberapa periode gelombang. Verifikasi: frekuensi terukur ≈ 1 kHz, duty cycle ≈ 50%.
Hubungkan OUT0 ke CLK1 (cascade). Program Counter 1 untuk membagi lagi 1 kHz menjadi 1 Hz (1 detik periode): count = 1000/1 = 1000 = 03E8H. CWR = 76H (Counter 1, low-high, Mode 3, binary). Kirim count ke port 41H. Hubungkan OUT1 ke osiloskop Channel B.
Program Counter 2 untuk freq berbeda, misalnya 100 Hz dari clock 1 MHz langsung: count = 1.000.000/100 = 10000 = 2710H. CWR = 0B6H (Counter 2, low-high, Mode 3, binary). Kirim ke port 42H. Hubungkan OUT2 ke osiloskop Channel C.
Amati ketiga channel osiloskop bersamaan: Channel A = 1 kHz (periode 1 ms), Channel B = 1 Hz (periode 1 s), Channel C = 100 Hz (periode 10 ms). Screenshot osiloskop.
Eksperimen: ubah count Counter 0 menjadi nilai ganjil (misal 999 = 03E7H). Amati bahwa duty cycle tidak tepat 50% — satu setengah periode 1 clock lebih panjang dari setengah periode lainnya.
Tugas Praktikum
Rancang rangkaian di Proteus dengan 8086 + 8253 + 3 osiloskop. Program harus menghasilkan 3 frekuensi dari 3 counter: Counter 0 = 500 Hz (dari clock 1 MHz langsung), Counter 1 = 10 Hz (cascade dari output Counter 0), Counter 2 = 2 Hz (cascade dari output Counter 1). Tampilkan screenshot osiloskop yang menunjukkan ketiga sinyal secara bersamaan. Hitung dan tuliskan semua nilai count dan Control Word di laporan. Tambahkan analisis: apa yang terjadi jika count di-set ke 0 atau 1?
Bank Kode Assembly
Data Movement
Pindah Data Antar Register & Memori
Assembly 8086
.model small
.stack100h.data
bil1 dw1234h
bil2 dw5678h
hasil dw0.codemulai:MOVAX, @dataMOVDS, AX; Pindah antar registerMOVAX, 1111hMOVBX, AXMOVCX, 2222hXCHGBX, CX; Pindah dari memori ke registerMOVAX, bil1
MOVBX, bil2
; Tukar isi dua memori via registerMOVAX, bil1
MOVBX, bil2
MOV bil1, BXMOV bil2, AXMOVAH, 4ChINT21hend mulai
Aritmatika
Penjumlahan, Pengurangan, Perkalian, Pembagian
Assembly 8086
.model small
.stack100h.data
a dw25
b dw7
hslJ dw0
hslK dw0
hslKl dw0
hslB dw0.codemulai:MOVAX, @dataMOVDS, AX; Jumlah: 25 + 7 = 32MOVAX, a
ADDAX, b
MOV hslJ, AX; Kurang: 25 - 7 = 18MOVAX, a
SUBAX, b
MOV hslK, AX; Kali: 25 * 7 = 175MOVAX, a
MUL b
MOV hslKl, AX; Bagi: 25 / 7 = 3 sisa 4MOVAX, a
CWDDIV b
MOV hslB, AXMOVAH, 4ChINT21hend mulai
Looping
Mencari Nilai Maksimum Array
Assembly 8086
.model small
.stack100h.data
arr dw25, 78, 13, 92, 45, 67, 31
n equ($-arr)/2
maks dw0.codemulai:MOVAX, @dataMOVDS, AXLEASI, arr
MOVCX, n
MOVAX, [SI]
DECCXADDSI, 2ulangi:CMPAX, [SI]
JGElanjutMOVAX, [SI]
lanjut:ADDSI, 2LOOPulangiMOV maks, AXMOVAH, 4ChINT21hend mulai
.model small
.stack100h.data
pola dw0001h,0002h,0004h,0008hdw0010h,0020h,0040h,0080h
n equ($-pola)/2.codemulai:MOVAX, @dataMOVDS, AX; Init 8255: Mode 0, Port A outputMOVDX, 63hMOVAL, 80hOUTDX, ALulangi:LEASI, pola
MOVCX, n
loop_led:MOVDX, 60hMOVAX, [SI]
OUTDX, AL; DelayMOVBX, 0FFFFhdelay:DECBXJNZdelayADDSI, 2LOOPloop_ledJMPulangiend mulai
Error Umum & Solusinya
Operand types must match
Penyebab: Mencampur ukuran operand berbeda.
Salah
MOVAL, 1234h
Benar
MOVAX, 1234h
Invalid effective address
Penyebab: Register tidak diizinkan dalam mode pengalamatan.
Salah
MOVAX, [CX]
Benar
MOVAX, [BX]
Cannot use segment register
Penyebab: Tidak bisa MOV langsung antar segmen atau ke immediate.
Salah
MOVDS, ES
Benar
MOVAX,ES lalu MOVDS,AX
Symbol not defined
Penyebab: Label/variabel belum dideklarasikan atau salah ketik.
Salah
MOVAX, pesen
Benar
Periksa penulisan nama (case-sensitive)
Tidak ada output
Penyebab: Lupa INT 21H, string tanpa $, atau DS belum di-set.