Dalam bab ini, kita membahas instruksi aritmetika dan logika. Instruksi aritmetika mencakup penjumlahan, pengurangan, perkalian, pembagian, perbandingan, negasi, penambahan (increment), dan pengurangan (decrement). Instruksi logika mencakup AND, OR, Exclusive-OR, NOT, pergeseran (shift), rotasi (rotate), serta perbandingan logis (TEST).
Bab ini juga membahas instruksi mulai dari prosesor 80386 hingga Core2, seperti XADD, SHRD, SHLD, pengujian bit (bit test), dan pemindaian bit (bit scan). Bab ini ditutup dengan pembahasan mengenai instruksi perbandingan string, yang digunakan untuk memindai data dalam bentuk tabel maupun membandingkan bagian-bagian data di memori. Kedua tugas perbandingan ini dapat dilakukan secara efisien dengan instruksi string scan (SCAS) dan string compare (CMPS).
Jika Anda terbiasa dengan mikroprosesor 8-bit, Anda akan menyadari bahwa set instruksi pada 8086 hingga Core2 lebih unggul dibandingkan sebagian besar mikroprosesor 8-bit, karena sebagian besar instruksinya memiliki dua operand, bukan hanya satu. Bahkan jika ini adalah pengalaman pertama Anda dengan mikroprosesor, Anda akan dengan cepat memahami bahwa mikroprosesor ini memiliki kumpulan instruksi aritmetika dan logika yang sangat kuat sekaligus mudah digunakan.
- Menggunakan instruksi aritmetika dan logika untuk menyelesaikan operasi aritmetika biner, BCD, dan ASCII sederhana.
- Menggunakan AND, OR, dan Exclusive-OR untuk melakukan manipulasi bit biner.
- Menggunakan instruksi shift dan rotate.
- Menjelaskan cara kerja instruksi mulai dari 80386 hingga Core2, seperti exchange and add, compare and exchange, double-precision shift, bit test, dan bit scan.
- Memeriksa isi suatu tabel untuk menemukan kecocokan dengan menggunakan instruksi string.
3. ADDITION, SUBTRACTION, AND COMPARISON[Kembali]
- Addition
Tabel 5–1 menunjukkan mode pengalamatan yang tersedia untuk instruksi ADD (mode pengalamatan ini mencakup hampir semua yang telah dijelaskan pada Bab 3). Namun, karena terdapat lebih dari 32.000 variasi instruksi ADD dalam set instruksi, tidak mungkin untuk mencantumkannya semua dalam tabel tersebut. Satu-satunya bentuk penjumlahan yang tidak diizinkan adalah memory-to-memory dan penggunaan segment register. Segment register hanya dapat dipindahkan (moved), dimasukkan ke stack (pushed), atau diambil dari stack (popped).
Perlu dicatat bahwa, seperti pada semua instruksi lainnya, register 32-bit hanya tersedia mulai dari prosesor 80386 hingga Core2. Pada mode 64-bit di prosesor Pentium 4 dan Core2, register 64-bit juga digunakan untuk operasi penjumlahan.
Penjumlahan Register.
Contoh 5–1 menunjukkan urutan instruksi sederhana yang menggunakan penjumlahan register untuk menjumlahkan isi dari beberapa register. Pada contoh ini, isi dari AX, BX, CX, dan DX dijumlahkan untuk membentuk hasil 16-bit yang disimpan di dalam register AX.
Setiap kali instruksi aritmetika dan logika dijalankan, isi dari flag register akan berubah. Perlu diperhatikan bahwa isi dari interrupt flag, trap flag, dan flag lainnya tidak berubah akibat instruksi aritmetika maupun logika. Hanya flag yang terletak pada 8 bit paling kanan dari flag register serta overflow flag yang mengalami perubahan. Flag-flag pada bagian kanan ini menunjukkan hasil dari operasi aritmetika atau logika.
Instruksi ADD, misalnya, akan mengubah isi dari sign flag, zero flag, carry flag, auxiliary carry flag, parity flag, dan overflow flag. Sementara itu, bit-bit flag tidak mengalami perubahan pada sebagian besar instruksi pemindahan data yang telah dibahas pada Bab 4.
Penjumlahan Immediate.
Penjumlahan immediate digunakan ketika data konstan atau data yang sudah diketahui ditambahkan. Contoh penjumlahan immediate 8-bit ditunjukkan pada Contoh 5–2. Pada contoh ini, register DL terlebih dahulu diisi dengan nilai 12H menggunakan instruksi immediate move. Selanjutnya, nilai 33H ditambahkan ke 12H di dalam register DL melalui instruksi immediate addition. Setelah penjumlahan, hasilnya (45H) masuk ke dalam register DL dan flag mengalami perubahan sebagai berikut:
Z = 0 1result not zero2P = 0
C = 0 1no carry2
A = 0 1no half-carry2
S = 0 1result positive2
P = 0 1odd parity2
O = 0 1no overflow2
Contoh 5–2
0000 B2 12 MOV DL,12H
0002 80 C2 33 ADD DL,33H
Penjumlahan Memory-ke-Register. Misalkan suatu aplikasi membutuhkan data dari memori untuk ditambahkan ke dalam register AL. Contoh 5–3 menunjukkan contoh yang menambahkan dua byte data berurutan, yang disimpan pada lokasi offset segmen data NUMB dan (lokasi berikutnya), ke dalam register AL.
EXAMPLE 5–3
0000 BF 0000 R MOV DI,OFFSET NUMB ;address NUMB
0003 B0 00 MOV AL,0 ;clear sum
0005 02 05 ADD AL,[DI] ;add NUMB
0007 02 45 01 ADD AL,[DI+1] ;add NUMB+1
Instruksi pertama memuat register destination index (DI) dengan alamat offset NUMB. Register DI, yang digunakan pada contoh ini, berfungsi untuk mengakses data di segmen data yang dimulai dari lokasi memori NUMB. Setelah nilai penjumlahan dihapus (diinisialisasi menjadi nol), instruksi ADD AL,[DI] akan menambahkan isi dari lokasi memori NUMB ke dalam register AL.
Selanjutnya, instruksi ADD AL,[ ] menambahkan isi dari lokasi memori NUMB ditambah 1 byte ke dalam register AL. Setelah kedua instruksi ADD dijalankan, hasil akhirnya akan muncul di dalam register AL sebagai jumlah dari isi NUMB ditambah isi dari lokasi berikutnya.
Penjumlahan Array.
Array memori adalah daftar data yang tersusun secara berurutan. Misalkan sebuah array data (ARRAY) berisi 10 byte, dengan penomoran elemen dari 0 hingga 9. Contoh 5–4 menunjukkan bagaimana cara menjumlahkan isi dari elemen array ke-3, ke-5, dan ke-7.
Pada contoh ini, register AL terlebih dahulu dihapus (diisi dengan 0), sehingga dapat digunakan untuk menampung hasil penjumlahan. Selanjutnya, register SI diisi dengan nilai 3 untuk pertama kali mengakses elemen array ke-3. Instruksi ADD AL,ARRAY[SI] kemudian menambahkan isi dari elemen array ke-3 ke dalam jumlah yang tersimpan di AL.
Instruksi berikutnya menambahkan elemen array ke-5 dan ke-7 ke dalam jumlah di AL, dengan menggunakan nilai 3 pada SI ditambah displacement 2 untuk mengakses elemen ke-5, serta displacement 4 untuk mengakses elemen ke-7.
EXAMPLE 5–4
0000 B0 00 MOV AL,0 ;clear sum
0002 BE 0003 MOV SI,3 ;address element 3
0005 02 84 0000 R ADD AL,ARRAY[SI] ;add element 3
0009 02 84 0002 R ADD AL,ARRAY[SI+2] ;add element 5
000D 02 84 0004 R ADD AL,ARRAY[SI+4] ;add element 7
Misalkan sebuah array data berisi bilangan 16-bit yang akan dijumlahkan untuk membentuk hasil penjumlahan 16-bit di dalam register AX. Contoh 5–5 menunjukkan urutan instruksi yang ditulis untuk prosesor 80386 dan yang lebih baru, dengan menggunakan bentuk pengalamatan scaled-index untuk menjumlahkan elemen ke-3, ke-5, dan ke-7 dari suatu area memori bernama ARRAY.
Pada contoh ini, EBX diisi dengan alamat ARRAY, sedangkan ECX berfungsi menyimpan nomor elemen array. Perhatikan bagaimana faktor skala (scaling factor) digunakan untuk mengalikan isi register ECX dengan 2 agar dapat mengakses data berupa word. (Ingat bahwa word terdiri dari 2 byte.)
Penjumlahan Increment.
Instruksi increment (INC) digunakan untuk menambahkan nilai 1 ke sebuah register atau lokasi memori. Instruksi INC dapat menambahkan 1 ke semua register atau lokasi memori, kecuali pada segment register. Tabel 5–2 menggambarkan beberapa bentuk instruksi increment yang tersedia pada prosesor 8086 hingga Core2. Sama seperti instruksi lain yang telah dibahas sebelumnya, tidak mungkin untuk menampilkan semua variasi instruksi INC, karena jumlahnya sangat banyak.
Pada increment memori tidak langsung (indirect memory increment), ukuran data harus dijelaskan dengan menggunakan direktif BYTE PTR, WORD PTR, DWORD PTR, atau QWORD PTR.
Assembler tidak dapat menentukan apakah, misalnya, instruksi INC [DI] merupakan increment dengan ukuran byte, word, atau doubleword. Instruksi INC BYTE PTR [DI] secara jelas menunjukkan bahwa data memori berukuran byte; instruksi INC WORD PTR [DI] menunjukkan bahwa data memori berukuran word; sedangkan instruksi INC DWORD PTR [DI] menunjukkan bahwa data memori berukuran doubleword. Pada operasi mode 64-bit pada prosesor Pentium 4 dan Core2, instruksi INC QWORD PTR [RSI] menunjukkan bahwa data memori berukuran quadword.
Contoh 5–6 menunjukkan bagaimana memodifikasi Contoh 5–3 untuk menggunakan instruksi increment dalam pengalamatan NUMB dan lokasi setelahnya. Pada contoh ini, instruksi INC DI mengubah isi dari register DI dari alamat offset NUMB ke alamat offset berikutnya. Kedua urutan program yang ditunjukkan pada Contoh 5–3 dan Contoh 5–6 sama-sama menjumlahkan isi dari NUMB dan lokasi berikutnya. Perbedaannya terletak pada cara pembentukan alamat melalui isi register DI dengan menggunakan instruksi increment.
EXAMPLE 5–6
0000 BF 0000 R MOV DI,OFFSET NUMB ;address NUMB
0003 B0 00 MOV AL,0 ;clear sum
0005 02 05 ADD AL,[DI] ;add NUMB
0007 47 INC DI ;increment DI
0008 02 05 ADD AL,[DI] ;add NUMB+1
Instruksi increment memengaruhi bit-bit flag, seperti halnya sebagian besar operasi aritmetika dan logika lainnya. Perbedaannya adalah instruksi increment tidak memengaruhi carry flag. Carry tidak berubah karena instruksi increment sering digunakan dalam program yang bergantung pada isi dari carry flag.
Perlu diperhatikan bahwa instruksi increment digunakan hanya untuk menunjuk ke elemen memori berikutnya dalam array data berukuran byte. Jika data yang diakses berukuran word, lebih baik menggunakan instruksi ADD DI,2 untuk memodifikasi pointer DI, dibandingkan menggunakan dua kali instruksi INC DI. Untuk array doubleword, gunakan instruksi ADD DI,4 untuk memodifikasi pointer DI.
Dalam beberapa kasus, carry flag harus dipertahankan, yang dapat berarti bahwa dua atau empat instruksi INC mungkin muncul dalam sebuah program untuk memodifikasi sebuah pointer.
Pengurangan
Banyak bentuk instruksi pengurangan (SUB) terdapat dalam set instruksi. Bentuk-bentuk ini menggunakan mode pengalamatan apa pun dengan data 8-, 16-, atau 32-bit. Bentuk khusus dari pengurangan (decrement, atau DEC) mengurangkan nilai 1 dari suatu register atau lokasi memori. Bagian 5–3 menunjukkan bagaimana data BCD dan ASCII dikurangkan. Sama seperti pada penjumlahan, angka yang lebih besar dari 16-bit atau 32-bit kadang-kadang harus dikurangkan. Instruksi subtract-with-borrow (SBB) digunakan untuk melakukan jenis pengurangan ini. Pada prosesor 80486 hingga Core2, set instruksi juga mencakup instruksi compare and exchange. Dalam mode 64-bit pada Pentium 4 dan Core2, pengurangan 64-bit juga tersedia.
Tabel 5–4 mencantumkan beberapa mode pengalamatan yang diizinkan dengan instruksi pengurangan (SUB). Ada lebih dari 1000 kemungkinan instruksi pengurangan, terlalu banyak untuk dicantumkan di sini. Satu-satunya jenis pengurangan yang tidak diizinkan adalah pengurangan memory-to-memory dan pengurangan register segmen. Seperti instruksi aritmetika lainnya, instruksi pengurangan memengaruhi bit-bit flag.
Pengurangan Register. Contoh 5–9 menunjukkan urutan instruksi yang melakukan pengurangan register. Contoh ini mengurangkan isi 16-bit dari register CX dan DX dari isi register BX. Setelah setiap pengurangan, mikroprosesor memodifikasi isi dari flag register. Flag berubah pada sebagian besar operasi aritmetika dan logika.
CONTOH 5–9
Pengurangan Immediate. Sama seperti pada penjumlahan, mikroprosesor juga mengizinkan operand immediate untuk pengurangan data konstan. Contoh 5–10 menyajikan urutan instruksi pendek yang mengurangkan 44H dari 22H. Di sini, pertama kita memuat nilai 22H ke dalam register CH menggunakan perintah immediate move.
Selanjutnya, instruksi SUB, menggunakan data immediate 44H, mengurangkan 44H dari 22H.
Setelah pengurangan, selisihnya (0DEH) dipindahkan ke dalam register CH. Flag berubah sebagai berikut untuk pengurangan ini:
CONTOH 5–10
Kedua carry flag (C dan A) menyimpan borrow setelah sebuah pengurangan, bukan carry seperti pada penjumlahan. Perhatikan pada contoh ini tidak terjadi overflow. Contoh ini mengurangkan 44H (68 desimal) dari 22H (34 desimal), menghasilkan 0DEH (–34 desimal). Karena hasil bertanda 8-bit yang benar adalah –34, maka tidak ada overflow pada contoh ini. Overflow 8-bit hanya terjadi jika hasil bertanda lebih besar dari +127 atau lebih kecil dari –128.
Pengurangan Decrement
Pengurangan decrement (DEC) mengurangkan 1 dari sebuah register atau isi suatu lokasi memori. Tabel 5–5 mencantumkan beberapa instruksi decrement yang menggambarkan decrement register dan memori.
Instruksi decrement pada data memori tak langsung memerlukan BYTE PTR, WORD PTR, DWORD PTR, atau QWORD PTR, karena assembler tidak dapat membedakan apakah lokasi yang dialamatkan register indeks berisi sebuah byte, word, atau doubleword. Sebagai contoh, DEC [SI] bersifat ambigu karena assembler tidak dapat menentukan apakah lokasi yang ditunjuk oleh SI adalah byte, word, atau doubleword. Dengan menggunakan DEC BYTE PTR [SI], DEC WORD PTR [DI], atau DEC DWORD PTR [SI], maka hal tersebut menjadi jelas.
Pengurangan dengan Borrow
Instruksi subtraction-with-borrow (SBB) berfungsi sama seperti pengurangan biasa, kecuali bahwa carry flag (C), yang menyimpan borrow, juga dikurangkan dari hasil selisih. Penggunaan paling umum dari instruksi ini adalah untuk pengurangan dengan lebar lebih dari 16-bit pada mikroprosesor 8086–80286 atau lebih dari 32-bit pada 80386–Core2.
Pengurangan lebar (wide subtraction) membutuhkan agar borrow dapat dipropagasikan melalui proses pengurangan, sama seperti penjumlahan lebar (wide addition) yang mempropagasikan carry. Tabel 5–6 mencantumkan beberapa instruksi SBB dengan komentar yang menjelaskan operasinya. Sama seperti instruksi SUB, SBB juga memengaruhi flag. Perhatikan bahwa instruksi pengurangan immediate dari memori dalam tabel ini membutuhkan arahan BYTE PTR, WORD PTR, DWORD PTR, atau QWORD PTR.
Ketika bilangan 32-bit yang disimpan pada register BX dan AX dikurangkan dari bilangan 32-bit yang disimpan pada register SI dan DI, carry flag mempropagasikan borrow di antara dua pengurangan 16-bit tersebut. Carry flag menyimpan borrow untuk pengurangan. Gambar 5–2 menunjukkan bagaimana borrow dipropagasikan melalui carry flag (C) dalam tugas ini. Contoh 5–11 menunjukkan bagaimana pengurangan ini dilakukan oleh sebuah program.
Pada pengurangan lebar, data 16-bit atau 32-bit yang paling rendah (least significant) dikurangkan dengan instruksi SUB.
Semua data berikutnya dan yang lebih signifikan dikurangkan dengan menggunakan instruksi SBB. Contoh ini menggunakan instruksi SUB untuk mengurangkan DI dari AX, kemudian menggunakan SBB untuk melakukan subtraction-with-borrow SI dari BX.
CONTOH 5–11
Perbandingan
Instruksi perbandingan (CMP) adalah sebuah pengurangan yang hanya mengubah bit-bit flag; operand tujuan tidak pernah berubah. Perbandingan berguna untuk memeriksa seluruh isi dari sebuah register atau lokasi memori terhadap nilai lain. Instruksi CMP biasanya diikuti oleh instruksi conditional jump, yang menguji kondisi bit-bit flag.
Tabel 5–7 mencantumkan berbagai instruksi perbandingan yang menggunakan mode pengalamatan yang sama seperti instruksi penjumlahan dan pengurangan yang telah dijelaskan sebelumnya. Sama seperti instruksi lainnya, bentuk perbandingan yang tidak diizinkan adalah memory-to-memory dan segment register compare.
Contoh 5–12 menunjukkan sebuah perbandingan yang diikuti oleh instruksi conditional jump. Pada contoh ini, isi dari register AL dibandingkan dengan 10H. Instruksi conditional jump yang sering mengikuti perbandingan adalah JA (jump above) atau JB (jump below). Jika JA mengikuti perbandingan, maka loncatan akan terjadi jika nilai dalam AL lebih besar dari 10H. Jika JB mengikuti perbandingan, maka loncatan akan terjadi jika nilai dalam AL lebih kecil dari 10H.
Dalam contoh ini, instruksi JAE mengikuti perbandingan. Instruksi ini menyebabkan program melanjutkan ke lokasi memori SUBER jika nilai dalam AL sama dengan atau lebih besar dari 10H. Ada juga instruksi JBE (jump below or equal) yang dapat mengikuti perbandingan untuk melakukan loncatan jika hasilnya lebih kecil atau sama dengan 10H.
Bab-bab selanjutnya akan memberikan detail tambahan tentang instruksi CMP dan instruksi conditional jump.
CONTOH 5–12
Compare and Exchange (Hanya pada Prosesor 80486–Core2)
Instruksi compare and exchange (CMPXCHG), yang hanya terdapat pada set instruksi prosesor 80486 hingga Core2, membandingkan operand tujuan dengan akumulator. Jika keduanya sama, operand sumber disalin ke operand tujuan; jika tidak sama, operand tujuan disalin ke akumulator. Instruksi ini berfungsi dengan data 8-, 16-, atau 32-bit.
Instruksi CMPXCHG CX,DX adalah contoh dari compare and exchange. Instruksi ini pertama-tama membandingkan isi CX dengan AX. Jika CX sama dengan AX, maka DX disalin ke AX; jika CX tidak sama dengan AX, maka CX disalin ke AX. Instruksi ini juga dapat membandingkan AL dengan data 8-bit dan EAX dengan data 32-bit jika operannya berupa data 8- atau 32-bit.
Pada prosesor Pentium hingga Core2, tersedia instruksi CMPXCHG8B yang membandingkan dua quadword. Ini adalah satu-satunya instruksi manipulasi data baru yang disediakan dalam Pentium–Core2 dibandingkan dengan versi mikroprosesor sebelumnya. Instruksi compare-and-exchange-8-bytes membandingkan nilai 64-bit yang terdapat dalam EDX:EAX dengan angka 64-bit yang berada di memori.
Sebagai contoh: CMPXCHG8B TEMP. Jika TEMP sama dengan EDX:EAX, maka TEMP diganti dengan nilai yang terdapat di ECX:EBX; jika TEMP tidak sama dengan EDX:EAX, maka angka yang terdapat di TEMP dimuat ke dalam EDX:EAX. Bit flag Z (zero) menunjukkan bahwa nilainya sama setelah perbandingan.
Instruksi ini memiliki bug yang dapat menyebabkan sistem operasi mengalami crash. Informasi lebih lanjut tentang kelemahan ini dapat diperoleh di www.intel.com. Terdapat juga instruksi CMPXCHG16B yang tersedia pada prosesor Pentium 4 ketika dijalankan dalam mode 64-bit.
PERKALIAN DAN PEMBAGIAN
Hanya mikroprosesor modern yang memiliki instruksi perkalian dan pembagian. Mikroprosesor 8-bit generasi awal tidak dapat melakukan perkalian atau pembagian tanpa menggunakan sebuah program yang melakukan perkalian atau pembagian dengan serangkaian operasi pergeseran (shift) dan penjumlahan atau pengurangan. Karena produsen mikroprosesor menyadari kekurangan ini, mereka menambahkan instruksi perkalian dan pembagian ke dalam set instruksi mikroprosesor generasi yang lebih baru.
Prosesor Pentium–Core2 memiliki rangkaian khusus yang dapat melakukan operasi perkalian hanya dalam satu periode clock, sedangkan pada mikroprosesor Intel generasi awal diperlukan lebih dari 40 periode clock untuk menyelesaikan perkalian yang sama.
Perkalian
Perkalian dilakukan pada byte, word, atau doubleword, dan dapat berupa bilangan bulat bertanda (IMUL) maupun bilangan bulat tak bertanda (MUL). Perlu dicatat bahwa hanya prosesor mulai dari 80386 hingga Core2 yang dapat mengalikan doubleword 32-bit.
Hasil dari sebuah perkalian selalu berupa produk dengan lebar ganda (double-width product). Jika dua bilangan 8-bit dikalikan, hasilnya adalah produk 16-bit; jika dua bilangan 16-bit dikalikan, hasilnya adalah produk 32-bit; dan jika dua bilangan 32-bit dikalikan, hasilnya adalah produk 64-bit. Dalam mode 64-bit pada prosesor Pentium 4, dua bilangan 64-bit dapat dikalikan untuk menghasilkan produk 128-bit.
Beberapa flag bit (overflow dan carry) akan berubah ketika instruksi perkalian dieksekusi dan menghasilkan keluaran yang dapat diprediksi. Flag lainnya juga ikut berubah, tetapi hasilnya tidak dapat diprediksi sehingga tidak digunakan.
Dalam perkalian 8-bit, jika 8 bit paling signifikan dari hasil bernilai nol, maka kedua flag C dan O bernilai nol. Flag ini menunjukkan apakah hasilnya berukuran 8-bit (C=0) atau 16-bit (C=1). Dalam perkalian 16-bit, jika 16 bit paling signifikan dari hasil bernilai nol, maka …
TABEL 5–8 Contoh instruksi perkalian 8-bit
Assembly Language | Operasi |
---|---|
MUL CL | AL dikalikan dengan CL; hasil perkalian tak bertanda (unsigned) berada di AX |
IMUL DH | AL dikalikan dengan DH; hasil perkalian bertanda (signed) berada di AX |
IMUL BYTE PTR[BX] | AL dikalikan dengan isi byte dari lokasi memori segmen data yang dialamatkan oleh BX; hasil perkalian bertanda berada di AX |
MUL TEMP | AL dikalikan dengan isi byte dari lokasi memori segmen data TEMP; hasil perkalian tak bertanda berada di AX |
Jika hasil perkalian adalah 0, maka kedua flag C dan O akan bernilai nol. Pada perkalian 32-bit, baik C maupun O menunjukkan bahwa 32 bit paling signifikan dari hasil perkalian bernilai nol.
Perkalian 8-Bit
Pada perkalian 8-bit, multiplicand (bilangan yang dikalikan) selalu berada di register AL, baik untuk operasi bertanda (signed) maupun tak bertanda (unsigned). Multiplier (bilangan pengali) bisa berupa register 8-bit apa pun atau lokasi memori.
Perkalian immediate tidak diizinkan, kecuali jika instruksi signed immediate multiplication khusus (yang akan dibahas lebih lanjut dalam bagian ini) digunakan dalam program. Instruksi perkalian hanya memuat satu operand karena operand tersebut selalu dikalikan dengan isi dari register AL.
Sebagai contoh, instruksi MUL BL akan mengalikan isi tak bertanda dari AL dengan isi tak bertanda dari BL. Setelah perkalian, hasil tak bertanda disimpan di AX—sebuah hasil dengan lebar ganda (double-width product). Tabel 5–8 menggambarkan beberapa instruksi perkalian 8-bit.
Misalkan BL dan CL masing-masing berisi dua bilangan 8-bit tak bertanda, dan bilangan tersebut harus dikalikan untuk menghasilkan produk 16-bit yang disimpan di DX. Prosedur ini tidak dapat dilakukan dengan satu instruksi saja, karena untuk perkalian 8-bit, hanya register AL yang dapat digunakan sebagai operand tetap.
Contoh 5–13 menunjukkan sebuah program singkat yang menghasilkan hal tersebut. Contoh ini memuat data 5 ke dalam register BL dan data 10 ke dalam CL. Produk perkalian (50) dipindahkan ke DX dari AX setelah perkalian, menggunakan instruksi MOV DX,AX.
CONTOH 5–13
Untuk perkalian bertanda (signed multiplication), hasilnya dalam bentuk biner jika positif, dan dalam bentuk komplemen dua (two’s complement) jika negatif. Bentuk ini sama dengan yang digunakan mikroprosesor untuk menyimpan semua bilangan bertanda positif maupun negatif. Jika program pada Contoh 5–13 mengalikan dua bilangan bertanda, maka instruksi MUL hanya diganti dengan IMUL.
Perkalian 16-Bit
Perkalian word (16-bit) sangat mirip dengan perkalian byte. Perbedaannya adalah bahwa AX berisi multiplicand, bukan AL, dan hasil 32-bit muncul di DX–AX, bukan hanya di AX. Register DX selalu berisi 16 bit paling signifikan dari hasil perkalian, sedangkan AX berisi 16 bit paling rendah. Sama seperti perkalian 8-bit, pilihan pengali (multiplier) terserah pada pemrogram. Tabel 5–9 menunjukkan beberapa instruksi perkalian 16-bit yang berbeda.
Perkalian Immediate 16-Bit Khusus
Mikroprosesor 8086/8088 tidak dapat melakukan perkalian immediate. Mulai dari 80186 hingga Core2, hal ini bisa dilakukan dengan menggunakan versi khusus dari instruksi perkalian.
Perkalian immediate ini harus berupa perkalian bertanda (signed multiplication), dan format instruksinya berbeda karena memuat tiga operand. Operand pertama adalah register tujuan 16-bit; operand kedua adalah register atau lokasi memori …
Operand kedua adalah register atau lokasi memori yang berisi bilangan 16-bit (multiplicand), dan operand ketiga adalah data immediate 8-bit atau 16-bit yang digunakan sebagai pengali (multiplier).
Instruksi IMUL CX,DX,12H mengalikan 12H dengan DX dan menyimpan hasil kali bertanda 16-bit ke dalam CX. Jika data immediate berupa 8-bit, maka data tersebut akan diperluas tanda (sign-extended) menjadi bilangan 16-bit sebelum perkalian dilakukan.
Contoh lainnya adalah IMUL BX,NUMBER,1000H, yang mengalikan NUMBER dengan 1000H dan menyimpan hasilnya ke dalam BX. Baik tujuan (destination) maupun multiplicand harus berupa bilangan 16-bit. Walaupun ini termasuk perkalian immediate, keterbatasan yang dimilikinya membuat penggunaannya tidak terlalu luas—terutama karena hanya berlaku untuk perkalian bertanda (signed multiplication) dan hasilnya terbatas pada 16-bit.
Perkalian 32-Bit
Pada 80386 dan yang lebih baru, perkalian 32-bit dimungkinkan karena prosesor ini memiliki register 32-bit. Sama seperti pada perkalian 8- dan 16-bit, perkalian 32-bit dapat berupa signed ataupun unsigned, dengan menggunakan instruksi IMUL dan MUL.
Dalam perkalian 32-bit, isi dari EAX dikalikan dengan operand yang ditentukan dalam instruksi. Hasilnya (64-bit) disimpan dalam pasangan register EDX:EAX, di mana EAX menyimpan 32-bit paling rendah dari hasil perkalian. Tabel 5–10 menunjukkan beberapa instruksi perkalian 32-bit yang tersedia pada 80386 dan seterusnya.
Perkalian 64-Bit
Hasil perkalian 64-bit pada Pentium 4 muncul dalam pasangan register RDX:RAX sebagai hasil 128-bit. Meskipun perkalian sebesar ini relatif jarang digunakan, Pentium 4 dan Core2 dapat melakukannya, baik pada bilangan bertanda (signed) maupun tak bertanda (unsigned). Tabel 5–11 menunjukkan beberapa contoh instruksi perkalian presisi tinggi ini.
Tidak ada komentar:
Posting Komentar