Pemrograman Aritmatika dan Perintah-perintahnya

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.

1.    7Dh (isi dari memory 40h) ditambahkan pada A dengan carry = 0 dan R7 = 0, dan isi counter R2 = 04.

2.    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.

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 ..

1.    jika nible bawah lebih besar dari 9, atau jika AC=1, nible bawah tersebut akan ditambah 6.

2.    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

 

1.    Buat 2’s complement dari pengurang (source).

2.    Tambahkan (ADD) pada bilangan yang dikurangi (A).

3.    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,..

1.    OV = 0 jika pembagi bukan bilangan 0.

2.    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.

 

1.    Tulis besaran dari bilangan biner 8-bit ((tanpa tanda)

2.    Balik (invert) setiap bit 1 jadi 0, 0 jadi 1.

3.    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:

 

1.    Ada Carry dari D6 ke D7

2.    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.

 


—————————————-

|o-o| Diterjemahkan oleh Dhanny Dhuzell

—————————————-

Tinggalkan Balasan