BAB 6
Sasaran
Setelah anda menamatkan bab ini , diharapkan anda dapat :
ð Menjelaskan range (jangkauan) data bilangan tak bertanda pada 8051
ð Membuat kode dari instruksi ADD dan SUBB pada bilangan tak bertanda.
ð Menjelaskan system BCD dari representasi data
ð Membedakan dan membandingkan data BCD packed dan unpacked.
ð Menulis kode untuk penjumlahan dan pengurangan pada data BCD
ð Membuat code 8051 untuk perkalian dan pembagian
ð Menjelaskan jangkauan data bilangan bertanda pada 8051.
ð Membuat kode dengan perintah aritmatika pada data bilenagan bertanda.
ð Memaparkan masalah carry dan overflow dan koreksinya.
Pada bab ini akan membahas seluruh instruksi aritmatika pada 8051 untuk operasi bilangan tidak bertanda maupun bilangan bertanda. Contoh program diberikan untuk menggambarkan aplikasi dari masing-masing perintah. SubBAB 6.1 kita membahas program dan instruksi yang berkaitan dengan addition (penambahan) dan subtraction (pengurangan) untuk bilangan tidak bertanda, termasuk untuk data BCD (biner Coded Decimal). Multiplication (perkalian) dan division (pembagian) kita bahas pada SubBAB 6.2. Sedang bilangan bertanda akan kita bahas pada subBAB 6.3
SubBAB 6.1 PENAMBAHAN DAN PENGURANGAN BILANGAN TIDAK BERTANDA
Bilangan bertanda diartikan sebagai data yang mana semua bit merupakan representasi dari data, dan tidak ada bit yang dugunakan sebagai tanda positif maupun minus. Hal ini berarti operand dapat berupa bilnangn 00 s/d FFh ( 0 – 255 desimal) dari data 8-bit. Topik bahasan mengenai bilangan bertanda akan kita bahas pada subBAB 6.3
Penambahan Bilangan Tidak Bertanda
Pada 8051, proses penambahan dua data, selalu melibatkan akumulator. Dan format perintah ADD adalah
ADD A,source ;A = A + source
Instruksi ADD digunakan untuk melakukan penambahan pada dua buah operand. Dan destination (tempat hasil dari proses) selalu pada A, sdang operand source dapat berupa register, data langsung, maupun memory. Ingat operasi aritmatika dari memory ke memory tidak diijinkan oleh assembler 8051. Instruksi ini dapat memperngaruhi bit-bit pada register PSW seperti AC (auxiliry Carry), C (carry), dan OV (OverFlow), tergantung dari hail operasi yang terjadi. Operasi yang mempengaruhi bit OV akan kita bahas pada subBAB 6.3 dalam bahasan mengenai bilangan bertanda. Mengingat yang saat ini dibahas adalah bilangan tidak bertanda, maka untuk sementara OV dapat kita abaikan. Lihat contoh 6-1
Contoh 6-1 |
Tunjukkan bagaimana register bendera (PSW) dapat terpengaruh oleh instruksi dibawah ini
MOV A,#0F5h ;A= F5 hex ADD A,#0Bh ;A= F5 + 0B = 0
Jawaban:
F5h 1111 0101 F5h + 1111 0101 + 100h 1111 0101
Setelah pejumlahan, register A destination) akan berisi 00 dan bedera adalah sebagai berikut
CY = 1 karena terdapat Carry keluar dari D7 PF = 1 karena jumlah 1s dari 0 adalah genal (nol). PF=1 AC = 1 karena ada carry dari D3 ke D4
|
Penambahan pada Byte Tunggal
Di BAB 2 terdapat contoh program untuk melakukan penjumlahan data 5 bytes. Jumlah setidaknya dibawah FFh, yang merupakan nilai maksimum yang dapat ditangai oleh register 8-bit. Untuk menghitung jumlah dari beberapa operand tersebut, bendera Carry harus selalu diperiksa setiap selesai satu perintah penjumlahan. Contoh 6-2 menggunakan R7 pada akumulator
Contoh 6-2 |
Anggaplah RAM pada lokasi 40-44 memlliki nilai sebagai berikut. Tulis program untuk mencari hasil dari penjumlahan pada A diakhri program, register A menjadi low-byte dan R7 sebagai high-byte.
40=(7D) 41=(EB) 42=(C5) 43=(5B) 44=(30)
Jawaban:
MOV R0,#40h ;isi pointer MOV R2,#5 ;isi counter Clr A MOV R7,A ;Clear R7 LAGI: ADD A,@R0 ;Tambahkan A dengan byte yg ditunjuk R0 JNC LANJUT ;Jika DY=0 jangann ditambhakan INC R7 ;simpan carry sebagai kelebiihan LANJUT: INC R0 ;Increment pointer DJNZ R2,LAGI ;ulagi sampai R2=0
|
Analisa dari contoh 6-2
Ada tiga kali proses dalam loop seperti yang ditunjukkan pda gambar di atas. Mempelajari program tersebut sebenarnya tergantung dari seberapa banyak kita berlatih.
- 7Dh (isi dari memory 40h) ditambahkan pada A dengan carry = 0 dan R7 = 0, dan isi counter R2 = 04.
- Kedua. Ebh (isi dari memory 41h) ditambahakn pula pada A, yang membuat A= = 68h dan CY =1. karena terdapat Carry, sekarang R7 di-increment. Dan sekarang Counter R2 = 3.
- kemudian C5h (isi dari memory 42h) ditambahkan ke A. Yang membuat A= 2Dh dan sekali lagi terdapat carry, R7 di-increment. Dan sekarang R2 = 2.
Pada saat loop berakhir. Hasil dari penjumlahan terdapat pada A dan R7, dimana A adalah low byte, sedang R7 adalah high byte.
ADDC dan Penjumlahan bilangan 16-bit
Saat kita melakukan penjumlahan dua bilangan 16-bit, kita harus memperhatikan status “simpan” dari Carry dari lower-byte ke high-byte. Instruksi ADDC (Add with Carry) dapat digunakan untuk hal tersebut. Misalnya, lihat penjumlahan 3CE7h + 3B8Dh, seperti di bawah ini.
1
3C E7
3B 8D +
78 74
Saat byte pertama dijumlahkan ( E7 + 8D = 74, CY = 1). Carry adalah status “simpan” untuk byte berikutnya, sehingga membuat 3C + 3B + 1 = 78 (semua dalam hex). Contoh 6-3 dibawah ini menunjukkan langkah diatas dalam program 8051.
Contoh 6-3 |
Tulis program untuk penjumlahan bilangan 16-bit. Angkanya adalah 3CE7h dan 3B8Dh. Tempatkan jumlahnya pada R7 dan R6, R6 sebagai low-byte.
Jawaban:
CLR C ;buat CY=1 MOV A,#0E7h ;isikan low-byte ADD A,#8Dh ;tambahkan, hasilnya A=74h dan CY=1 MOV R6,A ;simpan low-byte dari hasil penjumlahan MOV A,#3Ch ;isikan dengan high-byte ADDC A,#3Bh ;tambahkan bersama-sama carry MOV R7,A ;simpan hasil (high-byte) pada R7
|
System bilangan BCD (Biner Coded Decimal)
BCD adalah singkatan dari Biner Coded Decimal. BCD dibutuhkan karena dalam kehidupan sehari-hari kita selalu menggunakan digit 0 s/d 9 untuk menyebutkan bilangan, bukan biner maupun heksadesimal. Sedang bilangan biner yang merepresentasikan digit 0 s/d 9 disebut BCD. Lihat gambar 6-1. Dalam buku-buku tentang komputer, ada dua hal penting dalam bilangan BCD, yaitu (a) Unpacked BCD, dan (b) Packed BCD.
Digit BCD 0 0000 1 0001 2 0010 3 0011 4 0100 5 0101 6 0110 7 0111 8 1000 9 1001
|
Gambar 6-1 Code BCD
Unpacked BCD
Dalam Unpacked BCD, 4-bit terbawah adalah reprensentasi dari bilangan 0 s/d 9, sedang 4-bit lainnya dibiarkan 0. Contoh “0000 1001” dan “0000 0101” adalah unpacked BCD dari bilangan 9 dan 5. Unpancked BCD membutukan 1 byte memory atau register 8-bit untuk menyimpan satu data / bilangan BCD.
Packed BCD
Pada Packed BCD, setiap byte-nya mengandung dua bilangan BCD di dalamnya, satu terdapat pada 4-bit terbawah, dan satu lainnya terdapat pada 4-bit atas. Misalnya, “0101 1001” adalah packed BCD dari bilangan 59h. Dengan demikian cukup dibutuhkan satu byte memory untuk dapat menampung dua buah bilangan BCD. Hal jelas membuat lebih efisien dalam penyimpanan data BCD tersebut dua kali lebih baik.
Persoalan yang banyak timbul dalam penjumlahan bilangan BCD adalah, selalu dibutuhkan koreksi-koreksi agar hasil penjumlahan seperti yang kita harapkan. Hal ini karena CPU menjumlah dua data BCD seperti penjumlahan biasa, sebagai bilangan tidak bertanda, sehingga akan membuat hasilnya bukan lagi bilangan BCD. Lihat contoh di baah ini
MOV A,#17h
ADD A,#28h
Menjumlahkan dua bilangan tersebut akan menghasilkan 0011 1111b (3Fh) dimana itu bukan bilangan BCD. Tentu saja karena bilangan BCD harus memiliki digit 0000 – 0101 ( 0 – 9). Dengan kata lain, idealnya dalam menjumlah bilangan BCD kita akan mendapatkan bilngan BCD pula. Hasil yang semestinya adalah 17 + 28 = 45 (0100 0101). Nah untuk mengkoreksi masalah diatas, programer harus menambah dengan 6 (0110) pada 4-bit terbawah, sehingga hasil sebelumnya yaitu 3F + 06 = 45. Nah ini adalah yang seperti kita harapkan. Hal yang sama dapat terjadi pada 4-bit atas. Misalnya, 52h + 87h = D9h. Sekali lagi kita memperbaiki hasil tersebut dengan menambahkan angka 6 pada 4-bit teratas, D9h + 60h = 139h. Lihat bahwa 52 + 87 = 139. Perhatikan bahwa bilangan 4-bit bawah atau 4-bit atas dari hasil, jika lebih besar dari 9 haruslah ditambah dengan 6 untuk mendapatkan hasil yang benar. Namun 8051 telah menghindarkan kita dari kerepotan-kerepotan ini. 8051 memiliki sebuah instruksi yang dapat mendeteksi sebuah nible (4-bit), apakah lebih besar dari 9, dan akan menambahkan dengan 6 jika benar. Perintah tersebut adalah “DA” yang Decimal Adjustment. Instruksi DA ini hanya memiliki satu syntax saja, yaitu ..
DA A
, yang digunakan untuk meng-koreksi persoalan pada penjumlahan bilangan BCD seperti yang kita ketahui di atas.
Instruksi DA
Instruksi DA (Decimal Adjust for Addition) pada 8051 adalah dapat digunakan untuk mengkoreksi masalah yang timbul yang berkaitan denga penjumlahan bilangan BCD. Dan perintah ini hanya memiliki operand akumulator “A”. Instruksi ini akan menambah dengan 6 nible bawah ataupun nible atas jika dibutuhkan, namun jika tidak, nible tersebut tidak akan dirubah. Contoh dibawah ini akan menjelaskan.
MOV A,#47h ;A= 47h BCD pertama
MOV B,#25h ;B= 25h BCD kedua
ADD A,B ;hasilnya adalah 6Ch
DA A ;perbaiki menjadi 72h
Setelah program tersebut dilaksanakan, register A sekarang berisi 72h ( 47 + 25 = 72). Instruksi DA bekerja hanya terhadap A. Dengan kata lain, jika hendak mengkoreksi bilangan BCD pada register-register yang lain kita harus memindahkannya pada A terlebih dahulu. Dan juga harap dimengerti, bahwa Instruksi DA agar digunakan setelah perintah-perintah penjumlahan bilangan BCD, dimana tidak dibutuhkan hasil dengan digit bilangan lebih dari 9, seperti A s/d F. Satu yang terpenting adalah status CY dan AC saat sebelum instruksi DA dilaksanakan.
Adakalanya kita menginginkan meng-increment atau men-decrement bilangan BCD. Buku petunjuk melarang kita menggunakan perintah INC atau DEC sebelum DA, untuk melakukan hal itu. Hal ini mengingat instruksi INC dan DEC tidak mempengaruhi bendera-bendera sehingga sangat dimungkinkan hasilnya operasi menjadi salah. Buku petunjuk menyarankan agar kita menggunakan “ADD A,#01h” sebagai pengganti INC, dan “ADD A,#99h” sebagai pengganti DEC.
Ringkasan tentang DA
Instruksi ini dilakukan setelah perintah ADD atau ADDC dan ..
- jika nible bawah lebih besar dari 9, atau jika AC=1, nible bawah tersebut akan ditambah 6.
- jika nible atas lebih besar dari 9, atau jika CY=1, nible atas tersebut akan ditambah 6.
Dapat kita ketahui bahwa AC tidak pernah kita gunakan kecuali hanya untuk menjumlahan dan peng-koreksi-an bilangan BCD. Misalnya, menambah 29h dan 18h akan menghasilnya 41h, dimana itu jelas bukan hasil yang diharapkan sebagai penjumlahan bilangan BCD.
Hex BCD
29 0010 1001
18 + 0001 1000 +
41 0100 0001 AC=1
6 + 0110 +
47 0010 1001
karena AC=1, setelah penjumlahan “DA A” akan menambah 6 pada nible-bawah. Hasilnya kemudian adalah bilangan berformat BCD yang seperti kita harapkan.
Demikian instruksi DA ini adalah sangat bermanfaat dan sangat penting bagi kita untuk mengolah data berformat BCD.
Contoh 6-4 |
Anggaplah terdapat sejumlah data BCD yang tersimpan pada RAM mulai lokasi 40h seperti di bawah ini. Tulis program untuk mencari jumlah dari semua angka tersebut. Hasilnya haruslah juga BCD.
40=(71) 41=(11) 42=(65) 43=(59) 44=(37)
Jawaban:
MOV R0,#40h ;isi pointer MOV R2,#5 ;isi counter Clr A MOV R7,A ;Clear R7 LAGI: ADD A,@R0 ;Tambahkan A dengan byte yg ditunjuk R0 DA A ;Adjust untuk BCD JNC LANJUT ;Jika DY=0 jangan ditambahkan INC R7 ;simpan carry sbg kelebihan (nilai 100h) LANJUT: INC R0 ;Increment pointer DJNZ R2,LAGI ;ulagi sampai R2=0
|
Pengurangan bilangan tidak bertanda
SUBB A,source ;A = A – source – CY
Pada kebanyakan prosesor ada dua perbedaan perintah pengurangan SUB dan SUBB(Subtraction with borrow). Pada 8051 kita hanya diberikan SUBB. Namun kita tidak perlu kecewa karena SUBB bisa difungsikan sebagai SUB. Yaitu dengan membuat/memastikan CY=0 sebelum perintah SUBB dilaksanakan. Dengan demikian ada dua hal dalam SUBB yaitu (a) sebelumnya CY=0, dan (b) sebelumnya CY-1. Pertama kita akan membahas CY=0 sebelum SUBB.
SUBB (subtract with borrow) saat CY=0
SUBB dengan CY=0 sebelumnya, dapat juga dianggap SUB. Hal ini karena Borrow sebelumnya dianggap nol, atau tidak ada. Sehingga untuk membuat SUBB menjadi SUB, kita disarankan sebelumnya untuk men-clear-kan CY.
Dalam pengurangan, microprosessor 8051 seperti CPU modern lainnya menggunakan metode 2’s complement. Hal ini karena setiap CPU sudah menggunakan terlalu banya transistor di dalamnya untuk Adder (penambah), akan jauh lebih banyak jika CPU juga dilengkapi rangkaian transistor yang terpisah untuk pengurangan. Oleh karena itu CPU modern menggunakan adder yang sama yang digunakan oleh perintah-perintah penjumlahan, dengan sedikit penambahan modifikasi. Adapun proses dari SUBB tersebut akhirnya adalah sebagai berikut
- Buat 2’s complement dari pengurang (source).
- Tambahkan (ADD) pada bilangan yang dikurangi (A).
- Balik status CY
Namun kita bisa tenang, kesemua itu dilakukan oleh hardware 8051 dalam perintah SUBB ini. Sehingga perintah SUBB menjadi dapat digunakan dengan mudah oleh kita, seperti menggunakan perintah-perintah lainnnya. Walau sebenarnya di dalamnya adalah proses yang rumit. Kita hanya cukup mengetahui mana yang dikurangi, mana yang mengurangi, dan status CY, ditambah hasilnya mesti di mana.
Contoh 6-5 |
Tunjukkan 3 langkah proses seperti yang dijelaskan sebelumnya, untuk program di bawah ini.
CLR C ;buat CY=0 MOV A,#3Fh ;isi 3Fh pada A (A=3Fh) MOV R3,#23h ;isi 23h pada R3 (R3=23h) SUBB A,R3 ;pengurangan A- R3, hasil pada A
Jawaban: A = 3F 0011 1111 0011 1111 R3 = 23 0010 0011 + 1101 0011 2’s Complement 1C 1 0001 1100 0 CY=0 (langkah 3)
Bendera-bendera akan menjadi .. CY=0, AC=0, dan kita harus memeriksa kondisi Carry tersebut untuk mengetahui hasilnya positif atau negatif.
|
Jika setelah SUBB, CY=0 berarti hasilnya adalah bilangan positif, namun jika CY=1 maka hasilnya adalah negatif. Hasil negatif berada dalam bentuk 2’s complement. Besaran dari bilangan negatif tersebut dapat kita peroleh dengan cara menggunakan CPL (complement) dan INC(Increment) terhadap hasil tersebut. Misalnya jika kita mendapatkan -22, maka dengan menggunakan dua instruksi itu kita akan mendapat besaran 22 dari bilangan -22 tersebut. Lihat contoh 6-6
Contoh 6-6 |
Jelaskanlah program berikut ini.
CLR C ;buat CY=0 MOV A,#62h ;isi 62h pada A (A=3Fh) SUBB A,#6Eh ;pengurangan A – 6Eh JNC LANJUT ;jika CY=0 maka lompat CPL A ;jika CY=1 buat 1’s Complement INC A ;Lalu buat 2’s Complement LANJUT: MOV R1,A ;Simpan A pada R1
Jawaban:
Berikut ini adalah langkah-langkah untuk “SUBB A,6Eh”. 4C 0100 1100 0100 1100 6E 0110 1110 2’s Complement = 1001 0010 + -22 0 1101 1110
CY=1, hasilnya adalah negatif, dalam 2’s Complement.
|
SUBB (subtract with borrow) saat CY=1
Instruksi SUBB ini dapat digunakan untuk melakukan pengurangan multibyte, dengan memperhatikan bendera borrow (ingat dalam SUBB, bendera CY juga dinamakan Borrow). Maksudnya borrow adalah berarti “pinjam” dari operand yang lebih kecil tingkatnya. Lihat contoh 6-7
Contoh 6-7 |
Jelaskanlah program berikut ini.
CLR C ;buat CY=0 MOV A,#62h ;isi 62h pada A (A=3Fh) SUBB A,#96h ;pengurangan A – 96h = CCh dgn CY=1 MOV R7,A ;simpan hasilnya pada R7 MOV A,#27h ;A=27h SUBB A,#12h ;A = 27h – 12h – 1 = 14h (ingat status CY) MOV R6,A ;simpan hasil yang lain
Jawaban:
Setelah SUBB, A = 62 -96 = CCh, dan CY menjadi 1, yang menandakan bilangan pinjam. Mengingat CY=1, dan saat SUBB dilakasanakn ke dua kalinya. A = 27h – 12h -1 = 14h. Sehingga hasilnya utuhnya adalah 2762h – 14CC = 14CCh
|
SubBAB 6.2: PERKALIAN DAN PEMBAGIAN BILANGAN TIDAK BERTANDA
Dalam perkalian dan pembagian, pada 8051 akan selalu melibatkan register A dan B. Sebelumnya kita akan bahas perkalian.
Perkalian Bilangan Tidak Bertanda
8051 hanya mendukung perkalian byte dengan byte. Byte di sini adalah bilangan tidak bertanda. Sedang syntaxnya juga hanya satu, sebagaimana berikut
MUL AB ; A x B, hasilnya pada B dan A
Instruksi diatas tersebut adalah mengkalikan nilai register A dengan nilai di register B. Hasilnya dari perkalian tersebut adalah bilangan 16-bit. Register A digunakan sebagai penerima hasil byte-bawah sedang register B penerima hasil byte-atas. Contoh berikut ini adalah perkalian 25h dengan 65h. Hasilnya adalah data 16-bit pada register B dan A.
MOV A,#25h ;A = 25h
MOV B,#65h ;A = 65h
MUL AB ;B = 0Eh dan A = 99h
Tabel 6-1: Perkalian Bilangan Tidak Bertanda ( MUL AB )
Perkalian Operand-1 Operand-2 Hasil
Byte x Byte A B B = High Byte ; A = Low Byte
Catatan: jika kita menginginkan perkalian lebih dari 8-bit yang tidak didukung 8051, maka kita harus membuat sendiri rutin dari perintah dengan menggunakan beberapa MUL.
Pembagian Bilangan Tidak Bertanda
Untuk pembagian, 8051 juga hanya mendukung byte dibagi byte. Dengan syntax hanya sebagai berikut
DIV AB ;bagi A dengan B
Dalam pembagian byte dengan byte, yang dibagi selalu register A, dan yang membagi adalah register B. Setelah pembagian, register A menampung hasil baginya, dan register B menampung sisa dari pembagian tersebut. Lihat contoh dibawah.
MOV A,#95 ;A = 90 desimal
MOV B,#10 ;A = 10 desimal
DIV AB ;A = 9 (hasil) dan B = 5 (sisa)
Hal penting yang harus sedikit diperhatikan adalah bendera Overflow,..
- OV = 0 jika pembagi bukan bilangan 0.
- OV = 1 jika pembagi adalah bilangan 0. Hal untuk menunjukkan error. Dalam matematika biasa pembagi 0 akan membuat hasil menjadi tidak terhingga, yang tentu saja tidak bisa diimplementasikan pada komputer.
Tabel 6-2: Pembagian Bilangan Tidak Bertanda ( DIV AB )
Pembagian Dibagi Membagi Hasil Bagi Sisa Bagi
Byte/Byte A B A B
Aplikasi dari Instruksi Pembagian
Ada kalanya saat ADC (analog to Digital Converter) yang terhubung pada port dan ADC me-representasi-kan sebuah besaran dari temperature atau tekanan. ADC 8-bit memiliki jangkauan nilai 00 – FFh. Bilangan ini harus dikonversi ke bilangan desimal. Yaitu dengan cara membagi data tersebut dengan 10 sebanyak dua kali sehingga kita dapat memperoleh nilai ratusan, puluhan, dan satuan. Yang kemudian nilai-nilai tersebut dikonversi sebagai karakter ASCII dan ditampilkan pada LCD misalnya. Untuk lebih jelasnya lihat contoh 6-8.
Contoh 6-8 |
(a) Tulis data untuk mendapatkan data hex dalam jangkauan 00 – FFh dari port P1 dan ubahlah menjadi bilangan-bilangan desimal. Simpan digit-digit yang dihasilkan pada R7, R6, dan R5, di mana bit paling rendah adalah R7. (a) Jelaskan jalannya program, jika kita anggap data P1 adalah FDh.
Jawaban:
(a) MOV A,#0FFh MOV P1,A ;buat P1 sebagai port input MOV A,P1 ;baca data dari port MOV B,#10 ;B = 0Ah = 10 desimal DIV AB ;bagi dengan 10 MOV R7,B ;simpan sisa pada R7 (satuan) MOV B,#10 ; DIV AB ;Bagi dgn 10 sekali lagi MOV R6,B ;simpan nilai puluhan desimal MOV R5,A ;simpan nilai ratusan desimal
(b) untuk mengkonversi nilai biner ke desimal, kita harus membagi nilai tersebut dengan 10 desimal beberapa kali. Setiap sekali pemagian kita harus menyimpan sisa pembagiannya. Dalam hal ini akan menadapatkan FDh adalah sebagai 253 desimal seperti yang ditunjukkan di bawah ini.
Hasil Bagi Sisai FD/0A= 19 3 (satuan) 19/0A= 2 5 (puluhan) 2 (ratusan)
Akhirnya kita akan mendapatkan FDh = 253. Jika kita ingin menampilan karakter dari bilangan desimal tersebut, maka setiap digit bilangan tersebut harus dikonversi dulu pada format ASCII, yang akan dijelaskan pada BAB berikutnya.
|
SubBAB 6.3: OPERASI ARITMATIKA DAN KONSEP UNTUK BILANGAN BERTANDA
Selama ini kita membahas setiap data adalah sebagai bilangan tidak bertanda, dengan nilai terkecil adalah 0, tanpa memperhatikan biangan negatif. Namun beberapa aplikasi membutuhkan nilai yang lebih detil, misalnya menggunakan bilangan negatif. Selanjtnya kita akan membahas tentang konsep bilangan bertanda ini.
Konsep dari bilangan bertanda pada komputer
Dalam kehidupan sehari-hari kita biasa menggunakan bilangan negatif dan positif. Misalnya untuk suhu 5 derajat dibawah Nol, kita selalu menyebutnya menjadi -5. Dan 20 derajat di atas Nol kita sebut sebagai +20 (atau 20 saja). Komputer harus dapat mengakomodasi bilangan-bilangan ini. Para ahli komputer kemudian mencari format untuk bilangan ini (positif dan negatif) agar dapat diiplementasikan pada komputer. Akhirnya para ahli ini sepakat untuk menjadikan MSB (bit terbesar nilainya / bit paling kiri), dijadikan sebagai tanda negatif atau positif. MSB = 0 berarti bilangan tersebut adalah positif, dan MSB=1 untuk bilangan negatif.
Gambar 6-2: Format Operand untuk Bilangan Bertanda.
Bilangan Bertanda 8-bit
Pada bilangan bertanda , D7 (MSB) adalah “tanda”. Sedang D0 s/d D6 adalah besaran dari bilangan tersebut. Jika D7 = 0 maka bilangan tersebut adalah positif, dan jika D7 = 1 maka bilangan tersebut adalah bilangan negatif.
Bilangan Positif
Pada bilangan positif dapat di-representasi-kan dalam jangkauan 0 s/d +127 (lihat gambar 6-2). Namun untuk nilai lebih besar dari dari 127. Register 16-bit harus digunakan. Namun 8051 tidak mendukung data 16-bit, sehingga tidak akan kita bahas.
Bilangan Negatif
Untuk bilangan negatif, D7 = 1. Namun besaran yang ada harus dalam bentuk 2’s Complement (baca: Second Complement). Walaupun assembler dapat melakukanya, ada baiknya kita pelajari bagaimana cara membuat bilangan negatif pada bilangan biner.
- Tulis besaran dari bilangan biner 8-bit ((tanpa tanda)
- Balik (invert) setiap bit 1 jadi 0, 0 jadi 1.
- Tambahkan dengan 1.
Contoh 6-9, 6-10, 6-11 mendemontrasikan ketika langkah tersebut.
Contoh 6-9 |
Tunjukkan bagaimana 8051 merepresentasikan bilangan -5.
Jawaban:
Lihat langkah di bawah ini
1. 0000 0101 bilangan 5 dalam biner 2. 1111 1010 invert (balik) setiap bit-nya. 3. 1111 1011 tambahkan dengan 1
sehingga hasilnya, bilangan -5 dalam 8051 = FBh, yaitu merupakan 2’s Complement.
|
Contoh 6-10 |
Tunjukkan bagaimana 8051 merepresentasikan bilangan -34h.
Jawaban:
Lihat langkah di bawah ini
1. 0011 0100 bilangan 34h dalam biner 2. 1100 1011 invert (balik) setiap bit-nya. 3. 1100 1100 tambahkan dengan 1
sehingga hasilnya, bilangan -34h dalam 8051 = CCh, yaitu merupakan 2’s Complement.
|
Contoh 6-11 |
Tunjukkan bagaimana 8051 merepresentasikan bilangan -128.
Jawaban:
Lihat langkah di bawah ini
1. 1000 0000 bilangan 34h dalam biner 2. 0111 1111 invert (balik) setiap bit-nya. 3. 1000 0000 tambahkan dengan 1
sehingga hasilnya, bilangan -128 dalam 8051 = 80h, yaitu merupakan 2’s Complement.
|
Dari contoh di atas, jelas bagi kita bahwa jangkauan dari bilangan negatif 8-bit adalah -1 s/d -128. Daftar di bawah ini adalah bilangan bertanda dalam byte dan biner.
Desimal Biner Hex
-128 1000 0000 80
-127 1000 0001 81
-126 1000 0010 82
… … ..
– 2 1111 1110 FE
– 1 1111 1111 FF
0 0000 0000 00
1 0000 0001 01
2 0000 0010 02
… … ..
125 0111 1101 7D
126 0111 1110 7E
127 0111 1111 7F
Tepat di atas ini adalah penjelasan dari misteri dibalik pengalamatan relatif -128 s/d +127 pada instruksi Short Jump yang telah dijelaskan di BAB 3.
Masalah Overflow pada Operasi bilangan Bertanda
Saat mengunakan bilangan bertanda, masalah serius muncul yang harus kita hadapi. Ini adalah masalah Overflow. 8051 menampilkan masalah ini sebagai error dengan menbangkitkan bendera OV (Overflow), dan selanjutnya tinggal programmer yang akan membuat program berdasar bendera overflow ini. CPU hanya mengerti nilai 0s dan 1s, dan mengabaikan nilai manusia berkaitan dengan bilangan negatif dan positif. Lalu apa itu overflow? Jika sebuah perhitungan melebihi dari kapasitas bilangan yang tangani, misalnya 8-bit untuk 8051, maka terjadi overflow, dan programer harus diberitahu kondisi ini lewat bendera overflow tersebut. Lihat Contoh 6-12
Contoh 6-12 |
Telusuri kode di bawah ini dan jelaskan bagaimana akan hasil akhrinya
MOV A,#+96 ;A= 0110 0000 (A=60h) MOV R1,#+70 ;R1=0100 0110 (R1=46h) ADD A,R1 ;A = A + R1 ;A = A6h = -90 desimal = SALAH !!
Jawaban:
+ 96 0110 0000 + 70 0100 0110 + + 166 1010 0110 dan OV=1
Karena hasilnya penjumlahan adalah A6h, dan jika dibaca sebagai bilangan bertanda adalah -90, ini jelas tidak sesuai. Di mana 96 + 70 = -90, SALAH seharusnya +166. Oleh karena itu CPU akan mengaktifkan bendera (OV = 1) untu menandakan terjadi overflow.
|
Pada contoh 6-12, +96 ditambahkan dengan +70 dan hasilnya menjadi -90. Kenapa? Karena hasilnya adalah lebih besar dari nilai yang bisa ditampung A. Seperti register lainnya Akumulator hanya mampu menampung bilangan positif +127. Setiap CPU memiliki bendera OverFlow, khususnya untuk kegunaan memberitahu programmer jika hasil operasi bilangan bertanda terjadi kesalahan.
Kapan bendera OV tinggi?
Pada operasi bilangan bertanda 8-bit, OV akan di-set menjadi 1 jika ditemukan kondisi sebagai berikut:
- Ada Carry dari D6 ke D7
- atau Ada Carry dari D7 keluar
singkatnya OV = 1 hanya salah satu poin di atas terjadi, dan bukan kedua-duanya.
Contoh 6-13 |
Telusuri kode di bawah ini dan jelaskan bagaimana akan hasilnya
MOV A,#-128 ;A= 1000 0000 (A=80h) MOV R4,#-2 ;R4= 1111 1110 (R4=FEh) ADD A,R4 ;A = A + R4 ;A = 7Eh = +126 desimal = SALAH !!
Jawaban:
-128 1000 0000 – 2 1111 1110 + – 130 0111 1110 dan OV=1
Karena hasilnya penjumlahan adalah A6h, dan jika dibaca sebagai bilangan bertanda adalah -90, ini jelas tidak sesuai. Di mana -128 + -2 = +126, SALAH seharusnya -130. Oleh karena itu CPU akan mengaktifkan bendera (OV = 1) untu menandakan terjadi overflow.
|
Contoh 6-14 |
Pelajari kode di bawah ini dan jelaskan bagaimana akan hasilnya
MOV A,#-2 ;A= 1111 1110 (A=FEh) MOV R1,#-5 ;R1= 1111 1011 (R4=FBh) ADD A,R1 ;A = A + R1 ;A = F9h = -7 desimal = BENAR !!
Jawaban:
– 2 1111 1110 – 5 1111 1011 + – 7 1111 1001 dan OV=0
Hasilnya ternyata memang F9h, yang jika dibaca sebagai bilangan bertanda adalah -9. BENAR!! CPU tidak mengaktifkan bendera Overflow (OV = 0).
|
Contoh 6-15 |
Pelajari kode di bawah ini dan jelaskan bagaimana akan hasilnya …
MOV A,#+7 ;A= 0000 0111 (A=07h) MOV R1,#+18 ;R1= 0010 0010 (R4=12h) ADD A,R1 ;A = A + R1 ;A = 19h = +25 desimal = BENAR !!
Jawaban:
+ 7 0000 0111 + 18 0010 0010 + + 25 0010 1001 dan OV=0
Hasilnya ternyata memang 19h, yang jika dibaca sebagai bilangan bertanda adalah +25. BENAR!! CPU tidak mengaktifkan bendera Overflow (OV = 0).
|
Dari contoh-contoh di atas kita dapat menyimpulkan bahwa setiap penjumlahan bilangan bertanda OV mengindikasikan akan hasil dari operasi tersebut valid atau tidak. Sehingga kita dapat membuat rumusan, bahwa untuk operasi bilangan tidak bertanda maka bendera Carry (CY) adalah yang harus diperhatikan, sedang untuk operasi bilangan bertanda maka OverFlow(OV) yang harus kita perhatikan. Pada 8051, instruksi “JC LOKASI” dan “JNC LOKASI” memungkinkan bagi kita untuk men-cabang-kan program (branching) setelah operasi bilangan tidak bertanda, seperti yang kita lihat pada subBAB 6-1. Di lain pihak, tidak ada instruksi yang mudah untuk mendeteksi OV seperti kita mendeteksi CY. Namun kita dapat menggunakan Bit-Addressing yaitu dengan perintah “JB PSW.2,LOKASI” dan “JNB PSW.2,LOKASI”. Untuk Bit-Addresing kita akan bahas pada BAB 8.
RINGKASAN
Bab ini mendiskusikan instruksi-instruksi aritmatika untuk masing-masing data bilangan tidak bertanda dan bilangan bertanda pada 8051. Data tidak bertanda menggunakan 8-bit dari data, yang membuat jangkauan 00 s/d FFh. Sedang data bertanda memiliki jangkauan -128 s/d +127 desimal.
BCD atau Binary Coded Decimal adalah representasi dari digit 0 s/d 9 yang diimplementasikan pada bilangan biner. Dua format BCD yang dibahas adalah Unpacked BCD dan Packed BCD. 8051 memiliki instruksi khusus yang berkaitan dengan operasi BCD.
Dalam Operasi Artitmatika pada 8051, perhatian khusus harus diberikan pada kemungkinan dari berubahnya status bendera bendera seperti Carry dan OverFlow.