Minggu 7 Pemrograman

Bab 7: Set Instruksi: Aritmatika & Logika

Memahami instruksi matematika (ADD, SUB, MUL, DIV), operasi logika (AND, OR, XOR, NOT), dan operasi pergeseran (SHL, SHR, ROL, ROR).

Capaian Pembelajaran Bab Ini

Mahasiswa mampu menggunakan instruksi ADD/SUB untuk operasi matematika dasar, memahami perbedaan MUL dan IMUL, serta menerapkan operasi logika dan pergeseran bit untuk keperluan manipulasi data tingkat rendah.

7.1 Instruksi Aritmatika Dasar

Digunakan untuk menjumlahkan, mengurangi, atau menambah nilai variabel/pointer secara cepat. INC/DEC secara khusus tidak mengubah Carry Flag (CF), berbeda dengan ADD/SUB.

1. Penjumlahan Dua Register

Menjumlahkan isi AX dan BX, menyimpan hasil akhirnya di AX.

ADD AX, BX

2. Pengurangan Memori dari Register

Mengurangi nilai di memori (DS:[BX]) dengan register (AX). Hasilnya dimasukkan kembali ke register.

SUB AX, [BX]

⚠ Kesalahan Umum Mahasiswa

Menggunakan SUB AX, [BX] untuk mengurangi BX. Ini akan mengurangi BX dan menimpa AX. Jika tujuan Anda adalah mengurangi BX tanpa mengubah AX, gunakan SUB BX, AX.

3. Navigasi Pointer Array (Tanpa mengubah Carry Flag)

Menambah/mengurangi pointer array tanpa memicu apakah ada "pinjaman" (carry/borrow) di batas rentang. Sangat aman untuk navigasi pointer.

INC SI ; Pindah ke byte berikutnya (SI = SI + 1) DEC DI ; Mundur satu langkah ke belakang (DI = DI - 1)
Sebelum: SUB AL, AL
AL05H
Flags0000 0000
Setelah: SUB AL, AL
AL00H
Flags0000 0101
SUB AL, AL
Mengurangi angka dengan dirinya sendiri menghasilkan nol. Ini memicu CF=1 (borrow) dan ZF=1 (hasil nol).

7.2 Aturan Perubahan Flag pada Aritmatika

Setiap kali Anda menjalankan ADD, SUB, INC, atau DEC, prosesor secara otomatis memperbarui Register Flag. Memahami ini wajib hukumnya untuk membuat percabangan (seperti JA, JL).

Studi Kasus: ADD AL, AL (Jika AL awal = 10000000b)
Operand 1 (AL)
10000000
+
Operand 2 (AL)
10000000
Hasil di AL (Terpotong jadi 8-bit)
00000000
Bit ke-9 (1) jatuh dan masuk ke Carry Flag!
CF (Carry)1
ZF (Zero)1
OF (Overflow)1
SF (Sign)0
*OF=1 karena dua angka negatif (bit-7=1) dijumlahkan malah menghasilkan nol (positif).
FlagKapan Aktif (Bernilai 1)?
CFAda "pinjaman" (Borrow) pada SUB, atau ada "kelebihan" (Carry) keluar bit tertinggi pada ADD.
ZFHasil operasinya benar-benar nol (0).
SFBit paling kiri dari hasil akhir adalah 1 (dianggap negatif dalam bilangan bertanda).
OFTerjadi Overflow Bertanda. Contoh: Positif + Positif = Negatif, atau Negatif - Negatif = Positif.
PF & AFPF aktif jika jumlah bit '1' di hasil genap. AF aktif jika ada carry di bit ke-3 (hanya dipakai untuk instruksi BCD).

⚠ Pengecualian INC/DEC

Instruksi INC/DEC mengubah ZF, SF, OF, PF, AF, tapi tidak pernah mengubah CF. Ini agar pointer (SI/DI) bisa di-increment tanpa merusak status carry dari operasi matematika sebelumnya.

7.3 Perkalian & Pembagian (MUL, IMUL, DIV, IDIV)

Berbeda dengan ADD/SUB yang fleksibel, instruksi MUL dan DIV punya aturan ketat: salah satu operand wajib berada di register akumulator (AL/AX), dan hasilnya selalu berukuran 2x lipat dari operand asli.

1. Perkalian 8-bit (MUL)

Mengalikan AL dengan register 8-bit lainnya. Hasilnya selalu 16-bit, disimpan otomatis di AX.

; AL = 05H, BL = 10H MUL BL ; Hasilnya: AX = 0050H

2. Perkalian 16-bit (MUL)

Mengalikan AX dengan register 16-bit lainnya. Hasilnya selalu 32-bit, disimpan otomatis di pasangan DX:AX.

; AX = 1000H, BX = 0020H MUL BX ; Hasilnya: DX = 0000H, AX = 2000H

3. Perkalian 3-Operand (IMUL)

Keunggulan IMUL di prosesor modern: bisa menerima 3 operand untuk mengalikan langsung tanpa mengganggu register DX/AX.

; Kalikan BX dengan 10, simpan langsung di CX IMUL CX, BX, 10

4. Pembagian 16-bit (DIV)

Membagi nilai 32-bit di DX:AX dengan register 16-bit. Hasil baginya di AX, sisanya di DX.

; DX:AX = 0000:0050H, CX = 0010H DIV CX ; Hasil bagi: AX = 0005H, Sisa: DX = 0000H

⚠ Kesalahan Umum Mahasiswa

Mencoba membagi dengan 0 akan memicu Divide Error (Exception) yang langsung membuat program crash. Selalu pastikan pembagi tidak bernilai nol sebelum mengeksekusi instruksi DIV atau IDIV.

7.4 Persiapan Ukuran Data (CBW, CWD, NEG)

Karena MUL/DIV selalu melibatkan register pasangannya (AL<->AH atau AX<->DX), kita harus memastikan register pasangan tersebut tidak berisi sampah (garbage data) sebelum operasi dimulai.

⚠ Mengapa Ini Berbahaya?

Jika Anda ingin membagi AX (1000H) dengan BL (10H) menggunakan DIV, prosesor akan membaca DX:AX. Jika DX kebetulan berisi sampah (misal FFFFH), prosesor akan membagi FFFF:1000H bukan 0000:1000H. Hasilnya akan salah atau crash!

1. Mengubah Byte ke Word (CBW)

Mengopy bit ke-7 AL ke seluruh bit AH. Memastikan AX bersih dan siap untuk operasi aritmatika 16-bit.

; Jika AL = FFH (-1), maka CBW membuat AX = FFFFH (-1) CBW

2. Mengubah Word ke Double Word (CWD)

Mengopy bit ke-15 AX ke seluruh bit DX. Memastikan DX:AX bersih sebelum instruksi DIV 16-bit dieksekusi.

; Jika AX = FFF0H (-16), maka CWD membuat DX = FFFFH CWD

3. Membuat Bilangan Negatif (NEG)

Menghitung komplemen 2 (Two's Complement) dari register. Ini adalah cara tercepat untuk mengubah angka positif menjadi negatif.

; Jika AL = 00000001 (1), maka NEG AL menghasilkan 11111111 (-1) NEG AL

7.5 Operasi Logika Dasar

Digunakan untuk memanipulasi bit individu (AND, OR, XOR) atau seluruh bit (NOT). Sangat berguna untuk masking dan memeriksa bit spesifik.

Aturan Flag pada Logika

Instruksi AND, OR, XOR, dan NOT selalu menghapus (clear) CF dan OF menjadi 0. Hanya ZF, SF, dan PF yang berubah mengikuti hasil operasi.

1. Menghapus Bit Tertentu (AND)

Menghapus (masking) bit-bit yang di-AND-kan dengan angka 0. Bit yang di-AND-kan dengan 1 akan tetap utuh.

; Hapus 4 bit tinggi (bit 7-4), simpan 4 bit rendah AND AL, 0FH

2. Menyalakan Bit Tertentu (OR)

Memaksa bit menjadi 1 jika di-OR-kan dengan angka 1. Sering digunakan untuk mengaktifkan flag di register kontrol.

; Paksa bit ke-7 menjadi 1 (jadikan angka negatif) OR AL, 80H

3. Membalik Bit Tertentu (XOR)

Membalikkan (toggle) bit yang di-XOR-kan dengan angka 1 (0 jadi 1, 1 jadi 0). Bit yang di-XOR-kan dengan 0 tetap.

; Ubah huruf besar 'A' (41H) jadi kecil 'a' (61H) dengan membalik bit ke-5 XOR AL, 20H

⚠ Kesalahan Umum Mahasiswa

Mengira NOT AL sama dengan membuat bilangan negatif. NOT hanya membalik bit (One's Complement), tidak menambahkan 1. Untuk mengubah angka positif jadi negatif (Two's Complement) gunakan NEG AL.

7.6 Operasi Pergeseran & Perputaran (SHL, SHR, ROL, ROR)

Menggeser posisi bit ke kiri/kanan. Pada jaman dahulu, ini adalah trik utama programmer karena SHL jauh lebih cepat daripada instruksi MUL untuk perkalian pangkat 2.

Studi Kasus: SHL AL, 1 (Geser Kiri 1 Kali)
Sebelum: AL = 10110001 (B1H)
1 0 1 1 0 0 0 1
Sesudah: AL = 01100010 (62H)
0 1 1 0 0 0 1 0
Ujung kanan selalu diisi 0 CF = 1 (Bit yang terbuang)
Menggeser kiri 1 kali sama dengan mengalikan dengan 2. (B1H * 2 = 162H. Dipotong jadi 8-bit, jadinya 62H).

1. Geser Kiri untuk Perkalian (SHL)

Menggeser bit ke kiri. Bit yang keluar masuk ke Carry Flag (CF), ujung kanan diisi nol. Sama dengan mengalikan dengan 2 pangkat N.

; Kalikan AL dengan 8 (2 pangkat 3) dengan cepat SHL AL, 3

2. Geser Kanan untuk Pembagian (SHR)

Menggeser bit ke kanan. Bit yang keluar masuk ke CF, ujung kiri diisi nol. Sama dengan membagi bilangan bulat dengan 2 pangkat N.

; Bagi AL dengan 2 SHR AL, 1

3. Putar Bit Tanpa Hilang (ROL)

Memutar bit ke kiri melingkar. Bit yang keluar dari ujung kiri langsung dimasukkan kembali ke ujung kanan. Tidak ada data yang hilang.

; Tukar posisi 4 bit tinggi dan 4 bit rendah (misal: ABCD jadi BCDA) ROL AL, 4

7.7 Aturan Perubahan Flag pada Operasi Logika

Berbeda dengan aritmatika, operasi logika tidak menghasilkan Carry (CF). Flag yang berubah selalu adalah SF, ZF, dan PF.

OperasiSF (Sign)ZF (Zero)PF (Parity)
AND =1 jika bit ke-7 adalah 1 (dianggap negatif). =1 jika hasil akhirnya 0. =1 jika jumlah bit 1 genap (8-bit).
OR =1 jika bit ke-7 adalah 1. =1 jika hasil akhirnya 0. = 1 jika bit 1 genap.
XOR = 1 jika bit ke-7 berbeda dengan bit ke-6. = 1 jika hasil akhirnya 0. = 1 jika bit 1 genap.
NOT = 1 jika bit ke-7 adalah 0 (dianggap positif). = 1 jika hasil akhirnya 0. = 1 jika bit 1 genap.

7.8 Soal Latihan & Kuis

Soal 1. Apa perbedaan mendasar antara instruksi MUL dan IMUL pada prosesor 8086?

Lihat jawaban

MUL digunakan untuk perkalian bilangan unsigned (tak bertanda). Hasilnya selalu berukuran 16-bit (jika operand 8-bit) atau 32-bit. IMUL digunakan untuk perkalian signed (bertanda). Sintaksnya lebih ketat (harus ditulis sebagai 1 atau 3 operand), dan hasilnya bisa dibatasi ukurannya sesuai kebutuhan program.

Soal 2. Jika AL = 0FFH dan BL = 02H, berapa isi AX setelah instruksi MUL BL dieksekusi? (Anggap awalnya AX = 0000H)

Lihat jawaban

MUL BL menghitung AL * BL. Hasilnya: FFH × 02H = 01FEH. Karena ini adalah operasi 8-bit, hasilnya disimpan di register AX (16-bit), sehingga AX menjadi 01FEH. (Catatan: AH berisi 01H, AL berisi FEH).

Soal 3. Mengapa instruksi INC dan DEC tidak mempengaruhi Carry Flag (CF), sedangkan ADD dan SUB mempengaruhi CF?

Lihat jawaban

INC/DEC dirancang khusus untuk increment/decrement tanpa menganggapinya sebagai operasi aritmatika penuh. Ini memudahkan pengubahan pointer (seperti SI/DI) tanpa mengacaukan status carry dari operasi matematika sebenarnya. Jika Anda butuh operasi yang mengubah CF, gunakan ADD SI, 1 atau SUB SI, 1.

Soal 4. Apa fungsi instruksi CBW dan CWD? Mengapa mereka sangat penting sebelum instruksi DIV?

Lihat jawaban

CBW (Convert Byte to Word) mengubah AL (8-bit) menjadi AX (16-bit) dengan memperluas tanda (sign-extended). CWD (Convert Word to Double Word) mengubah AX (16-bit) menjadi DX:AX (32-bit). Pada DIV, prosesor membaca pasangan register (DX:AX). Jika DX berisi sampah (bukan nol atau ekstensi tanda yang benar), hasil pembagian akan sepenuhnya salah atau menyebabkan crash (Divide Error).

Kuis Bab 7

1. Setelah instruksi `SUB AL, AL` dieksekusi, bagaimana kondisi AL dan Flag yang pasti berubah?

2. Instruksi logika mana yang paling tepat digunakan untuk membalikkan (toggle) status bit ke-7 AL tanpa mempengaruhi 7 bit lainnya?

3. Apa perbedaan utama antara instruksi SHL (Shift Left) dengan ROL (Rotate Left)?

4. Jika DL = 80H (10000000b), apa hasilnya setelah instruksi `SHR DL, 1` dieksekusi?

5. Mengapa instruksi IMUL lebih sering digunakan oleh programmer modern dibandingkan MUL untuk operasi perkalian biasa?