Minggu, 19 Juni 2011

ARITMETIKA

            Perhitungan aritmetik dalam bahasa assembly melibatkan type bilangan integer dan floating point. Intruksi-instruksi yang terdapat pada proses perhitungan aritmetik adalah instruksi geser, putar, penjumlahan, pengurangan, perkalian, pembagian dan perintah-perintah lain. Instruksi-instruksi tersebut melakukan operasi pada operand dengan lebar 8-bit atau 16-bit.



2.1    INSTRUKSI GESER DAN ROTASI

            Instruksi geser dan rotasi berfungsi untuk mengubah posisi bit operand. Berikut ini instruksi geser dan rotasi dengan beberapa variasinya :

            SHL (Shift Left)                     = geser kiri
            SHR (Shift Right)                   = geser  kanan
            SAL (Shift Arithmetic Left)   =geser kiri aritmetik
            SAR (Shift Arithmetic Right) = geser kanan aritmetik
            ROL (Rotate Left)                  = Rotasi Kiri
            ROR (Rotate Right)               = Rotasi Kanan
            RCL (Rotate Carry Left)        = Rotasi kiri dengan carry
            RCR (Rotate Carry Right)      = Rotasi kanan dengan carry




Instruksi SHL
            Instruksi SHL menggeser setiap bit operand ke kiri, mengisi bit terendah dengan nilai nol. Bit tertinggi dipindah ke CF (Carry Flag) dan bit dala CF ditimpa.

           
Keterangan :
            Penomoran bit dimulai dari bit yang paling kanan. Bit paling kanan adalah bit dengan nomor yang paling rendah sering disebut LSB(Left Significant Bit), sementara bit yang paling kiri adalah bit dengan penomoran yang paling tinggi sering disebut MSB (Most Significant Bit).
Sintaknya sebagai berikut :
SHL    dest, 1
SHL    dest, CL

CL tidak diubah ketika instruksi SHL menggunakannya sebagai counter geser. Berikut ini contoh penggunaan instruksi SHL pada operand memory :
Shl bl, 1
Shl wordval, 1
Shl byte ptr[si], 1
Mov cl, 4         ; isi CL=4 artinya proses penggeserannya sebanyak 4 bit
Shl al, cl

Pada contoh berikut, BL digeser sekali ke kiri. Bit tertinggi disalin ke dalam register CF (carry flag), dan bit paling rendah diisi dengan nilai nol :
Mov bl, 8Fh    ; BL = 10001111b
Shl bl, 1                       ; BL = 00011110b, CF = 1
Contoh berikut akan menggeser DX ke kiri sebanyak 3 bit :
Mov dx, 000Fh           ; DX 0000000000001111b
Mov cl, 3         ; jumlah geser = 3
Shl dx, cl         ; 0000000000111000b


Instruksi SHR
            SHR berfungsi untuk menggeser setiap bit ke kanan dan mengganti bit tertinggi dengan nilai nol. Bit paling rendah disalin ke dalam CF, dan bit dalam CF ditimpa :


Sintak instruksi SHR :
SHR dest, 1
SHR dest, CL

Nilai CL setelah instruksi SHR selesai tidak berubah. Berikut ini contoh penggunaan instruksi SHR dengan operand register dan memory :
Shr bl, 1
Shr wordval, 1
Shr byte ptr [si], 1
Mov cl, 4
Shr al, cl


Instruksi SHR dapat digunakan untuk membagi bilangan dengan 2 contoh, kita dapat membagi 32 dengan 2, sebagai berikut :
Mov dl, 32      ; DL = 00100000b
Shr dl, 1          ; DL = 00010000 = 16

Instruksi SAL dan SAR
            Instruksi SAL dan SAR adalah instruksi penggeseran yang khusus untuk bilangan bertanda. Instruksi SAL mrip dengan instruksi SHL dan disertakan dalam set instruksi hanya untuk pelengkap. SAR menggeser setiap bit ke kanan dan menyalin bit tanda (MSB). Setelah instruksi SAR dijalankan, nilai MSB tidak berubah.




Sintaknya sebagai berikut :
SAR dest, 1
SAR dest, CL
SHR dest, 1
SHR dest, CL

Contoh berikut menunjukan bagaimana SAR menggandakan bit tanda. AL bernilai negative sebelum dan sesudah digeser ke kanan :
Mov al, 0F0h   ; AL = 11110000b (-16)
Sar al, 1                       ; AL = 11111000b (-8), CF = 0

Contoh berikut, -32768 digeser ke kanan 5 kali. Proses ini sama dengan membagi bilangan dengan 2 pangkat 5 (32). Hasilnya adalah -1024 :
Mov dx, 8000h           ; DX = 1000000000000000b = -32768
Mov cl, 5
Sar dx, cl         ; DX = 1111110000000000b = - 1024



Instruksi ROL (Rotate Left)
            Instruksi ROL memindahkan setiap bit ke kiri. Bit tertinggi disalin ke dalam CF dank e bit terendah sebagai berikut :

Sintaknya sebagai berikut :
ROL dest, 1
ROL dest, CL

Contoh berikut menggambarkan penggunaan ROL pada nilai byte dan word :
Byte_value :
Mov cl, 4
Mov cl, 26h
Rol al, cl
Rol byteval, cl
Word_value :
Mov cl, 8
Mov ax, 0203h
Rol ax, cl
Rol wordval, cl
………..
……….
Byteval db 0Fh
Wordval dw 1234h





Instruksi ROR
            Instruksi ROR (Rotate Right) memindahkan setiap bit ke kanan. Bit paling rendah disalin ke dalam CF dank e bit tertinggi pada saat yang sama.


Sintaknya sebagai berikut :
ROR dest, 1
ROR dest, CL

Contoh berikut menggambarkan bit terendah disalin ke dalam CF dank e dalam bit tertinggi :
Mov al, 01h     ; AL = 00000001b
Ror al, 1          ; AL = 10000000b, CF = 1
Ror al, 1          : AL = 01000000b, CF = 0

Instruksi RCL dan RCR
            Instruksi RCL menggeser setiap bit ke kiri dan menyalin bit tertinggi ke dalam CF. CF disalin ke dalam bit terendah, sebagai berikut :


Dalam contoh ini, instruksi CLC menghapus nilai CF. instruksi RCL pertama memindahkan tinggi  ke dalam CF, dan menggeser semua bit lainnya ke kiri. Instruksi RCL kedua memindahkan CF ke dalam posisi bit terendah, dan menggeser semua bit yang lain ke kiri :
Clc                   ; CF = 0
Mov bl, 88h     ; BL = 10001000b
Rcl bl, 1                       ; BL = 00010000b, CF = 1
Rcr bl, 1          ; BL = 00100001b, CF = 0

Instruksi RCR. Instruksi ini menggeser setiap bit ke kanan dan menyalin bit terendah ke dalam CF. CF disalin ke dalam bit tertinggi :

Pada contoh berikut , STC menset CF sebelum melaksanakan rotasi :
Stc                   ; CF = 1
Mov ah, 10h    ; AH = 00010000b, CF = 1
Rcr ah, 1          ; AH = 10001000b, CF = 0




2.2 APLIKASI GESER DAN ROTASI
Instruksi geser dan rotasi digunakan sewaktu-waktu. Berikut ini beberapa contoh aplikasi yang menggunakan perintah tersebut.


APLIKASI MENGGESER BEBERAPA BYTE
Misalkan kita akan menggeser semua bit di dalam table ke kanan, seperti pada gambar grafik bit-map. Misalnya digunakan tiga byteoperand, kita dapat memulai dengan byte yang paling kiri, menggeser bit rendahnya dalam CF, hasil penggeseran sekali ke kanan adalah sebagai berikut:

                        Byte 1                         byte 2                          byte 3
Sebelum:         00111011                    01000110                    11111111
Sesudah:          00011101                    10100011                    01111111

Setelah digeserkan, bytel sama dengan 00011101 dan CF = 1, kemudian RCR di gunakan  untuk merotasi byte 2 ke kanan ketika menyalin isi CF ke dalam bit posisi tertinggi byte 2. sesudah rotasi, byte 2 sama dengan 10100011b. terakhir, byte 3 rotasi ke kanan, menghasilkan 0111111b.

Tiga tahap diulangi setiap kali kita menggeser semua bit dalam ketiga byte. Intruksi berikut menggeser bit dalam semua byte ke kanan empat kali. Berikut ini contoh program untuk implementasi fungsi tersebut.
                        Mov cx, 4
            L1 :      shr byte 1, 1
                        rcr  byte 2, 1
                        rcr byte  3, 1
                        loop L1
            byte1 db 3 Bh
            byte2 db 46h
            byte3 db 0FFh



PERKALIAN DAN PEMBAGIAN
Seperti yang di jelaskan sebelumnya bahwa intruksi SHL dan SHR dapat digunakan untuk operasi perkalian dan pembagian dengan efesiensi ketika satu operand-nya merupakan pangkat dari 2. (misalnya 2,4,8,16….)

Jika operand-nya bukan pangkat dari 2, kita bisa memfaktorkannya sehingga salah satu faktornya adalah bilangan pangkat dari 2. misal, untuk mengalikan bilangan nilai dalam BX dengan 36, kita memanfaatkan keuntungan dengan aturan perkalian distribusi sebagai berikut:
            BX * 36 = BX * (32+4)
                        = (BX* 32) + (BX * 4)
Berikut ini contoh penggunaan intruksi SHL dalam perkalian variabel 16-bit dengan 36. hasilnya, 360 yang merupakan penjumlahan dua perkalian, yaitu 320 dan 40 :
            Mov bx, intval
            Mov cl, 5
            Shl bx, cl
            Mov product, bx
            Mov bx, intval
            Shl bx, 1
            Shl bx, 1
            Add product, bx
            Intval dw 0Ah
            Product dw?




MENAMPILKAN BILANGAN DALAM BINER ASCII
Cara yang baik untuk mengaplikasikan intruksi SHL adalah menampilkan byte dalam format biner ASCII. Kita dapat mengambil memanfaatkan register CF. register CF menyalin nilai bit tertinggi setiap kali byte digeser ke kiri.

Program tampil. ASM berikut menampilkan setiap bit dalam register AL. Keluarannya adalah pola bit 6Ch : 01101100.
            Title tampilan ASCII biner
            Dosseg
            .model small
            .stack 100h
            .code
            Main proce
                        mov al, 6Ch
                        mov cx, 8
            L1 :      shl al, 1
                        Mov dl,’0’
                        Jnc L2
                        Mov dalam, ‘1’
            L2 :      push ax
                        Mov ah, 2
                        Int 21h
                        Pop ax
                        Loop L1

                        Mov ax, 4000h
                        Int 21h
            Main endp
            End main


MENGISOLASI STRING BIT

Untuk mengambil sebuah field, kita dapat menggeser bit-bit ke kanan pada alamat terendah register DX. Cara ini dapat di lakukan dengan menggunakan intruksi SHR. Setelah digeser kanan, kemudian bit yang tidak relevan di-AND-kan dengan nol. Berikut ini contoh mengambil hari dari register DX:
            mov al, dl
            and al, 00011111b
            mov day, al
untuk mengambil nilai bulan, berikut inicontohnya:
            mov ax, dx
            mov cl, 5
            shr ax, cl
            and al, 00001111b
            mov month, al
untuk mengambil nilai tahun, contohnya sebagai berikut:
            mov al, dh
            shr al, 1
            mov ah, 0
            add ax, 1980
            mov year, ax

2.3 PENJUMLAHAN DAN PENGURANGAN KOMPLEK
Penjumlahan dan pengurangan komplek melibatkan beberapa register dan melibatkan beberapa proses yang lumayan komplek sehingga diistilahkan sebagai penjumlahan dan pengurangan komplek.

INTRUKSI ADC(ADD WITH CARRY)
Intruksi ADC berfungsi untuk menjumlahkan dan mengurangkan dengan operand banyak byte dan banyak word. Nilai operand sumber dan register CF keduanya ditambahkan ke dalam operand tujuan. sintaknya sebagai berikut:

            ADC tujuan,sumber
Lebar operand sumber dan tujuan bisa 8-bit ataupun 16-bit

Berikut ini contoh penjumlahan dua operand multiword dan kemudian menyimpannya dalam memori. Fungsi ini di lakukan dalam prosedur MULTIWORD_ADD. Dalam prosedur ini diasumsikan bahwa setiap nilai disimpan dengan least significant pada alamat paling rendah:
            Title contoh penjumlahan multiword
            Dosseg
            .model small
            .stack 100h
            .code
            Main proc
                        Mov ax,@data
                        Mov ds,ax
                       
                        Mov si,offset op 1
                        Mov di,offset op 2
                        Mov bx, offset result
                        Mov cx,2
                        Call multiword_add

                        Mov ax, 4000h
                        Int 21 h
            Main endp
            .data
Op1 dd                        02B2A406h
Op2 dd                        080108700h
Result              dw       3 dup(0)
.code
            Multiword_add proc
                        Push ax
            Push bx
            Push cx
            Push si
            Push di
            Clc
           
            L1:
                        Mov ax, [si]
                        Adc ax,           [di]
            Pushf
            Mov [bx], ax
            Add si, 2
            Add di, 2
            Add bx, 2
            Popf
            Loop L1
            Adc word ptr[bx], 0
            Pop di
            Pop si
            Pop cx
            Pop bx
            Pop ax
            Ret
            Multiword_add endp
            End main

INTRUKSI SBB (SUBSTRACT WITH BORROW)
Intruksi SBB berguna untuk pengurangan multibyte atau multiword.
Sintaknya sebagai berikut:

SBB tujuan,sumber
Lebar operand tujuan dan sumber dapat 8-bit atau 16-bit. Proses pertama, operand sumber dikurangkan dari tujuan, kemudian CF dikurangkan dari tujuan.

Contoh program quadword, yang melakukan proses pengurangan pada operand quadword (8-byte), sebagai berikut:
            mov cx, 8
            mov si, 0
            clc
L1 :
            mov al, byte ptr op1 [si]
            sbb al, byte ptr op2 [si]
            mov byte ptr result [si], al
            inc si
            loop L1
            …….
            …….
Op1                 dq                    20403004362047A1h
Op2                 dq                    055210304 A2630B2h
Result              dq                    0

Intruksi SBB pada baris ke-6 berfungsi mengurangkan  nilai CF dan isi dari op2 dari AL.

Perintah DQ menyimpan byte dalam memori dengan urutan terbalik. Proses pengurangan dapat diringakas sebagai berikut:
            Op1     20        40        30        04        36        20        47        A1h
            Op2     05        52        10        30        4A       26        30        B2h




            Hasil    1A       EE       IF        D3       EB       FA       16        EF
Pada contoh ini op1 lebih besar dari op2 sehingga hasilnya positif. Jika hasilnya negatif, CF akan diset juga setelah loop selesai, dan hasilnya akan disimpan dalam bentuk two’s complement.

2.4 PERKALIAN DAN PEMBAGIAN
Terdapat intruksi untuk melaksanakan perkalian dan pembagian integer pada bilangan 8-bit dan 16-bit. Semua operand diasumsikan bilangan biner. Jadi, jika terdapat operand bilangan decimal maka harus dibuat penyesuaian ke dalm biner. Operasi floating-point ditangani oleh coprosesor matematika Intel terpisah atau emulasi perangkat lunak yang di dukung oleh library dalam bahasa pemrograman. Intruksi MUL (multiply) dan DIV (divide)
Digunakan untuk bilangan integen biner bertanda.

INTRUKSI MUL DAN IMUL
Intruksi MUL dan IMUL mengalikan operand 8-bit atau 16-bit dengan AL atau AX. Jika operand sumber yang ada lebarnya 8-bit maka otomatis perkalian dengan AL dan hasilnya disimpan dalam AX dan hasilnya disimpan dalam DX dan AX (16 bit yang lebih tinggi dalam DX) format sintaknya sebagai berikut:
            MUL sumber
            IMUL sumber
Operand sumber  mungkin berupa operand register atau memori, tetapi tidak boleh data immediate. Contoh perkalian AL dengan 10h:
            Mov al, 5h
            Mov bl, 10h
            Mul bl
            Mov ax,val1
            Mul val2
            ……
            …..
Val 1               dw                   2000h
Val 2               dw                   0010h
Perkalian intergen 1 dengan byte 1 dan menyimpan hasilnya dalam variable 32-bit yang diberi nama result:
            Mov ax, integer 1
            Mov bh, 0
            Mov bl, byte 1
            Mul bx
            Mov word ptr result, ax
            Mov word ptr result+2, dx
            ……
            …..
            Byte1              db        20h
            Integer 1          dw       1234h
            Result              dd        ?

INTRUKSI IMUL
Intruksi IMUL mengalikan nilai biner tidak bertanda. Untuk perkalian 8-bit, IMUL menggunakan register CF dan OF dengan cara menset CF=1 dan OF=1. untuk perkalian 16-bit, CF dan OF diset 1. tiga contoh berikut mengilustrasikannya intruksi IMUL:
            Operasi 8-bit : 48 x 4= 192
            Mov al, 48
            Mov bl, 4
            Imul bl
Hasil kali dalam AX adalah  00C0h (+192). Oleh karena AH bukan perpanjangan tanda AL, CF dan OF diset 1. hal ini memberi tahu kita bahwa sign magnitude hasil lebih besar dari 8 bit:
            Operasi 8-bit : -4 x 4 = -16
            Mov al, -4
            Mov bl, 4
            Imul bl
Hasil kali dalam AX adalah FFF0h (-16) dan AH adalah perpanjangan tanda AL. dalam kata lain, hasil bertanda dapat disimpan dalam AL.
            Operasi 16-bit : 48 x 4 = 192
            Mov ax, 48
            Mov bx, 4
            Imul bx
Hasil kali dalam DX : AX adalah 000000C0h. oleh karena tanda DX dan AX adalah sama (positif), hasilnya dapat disimpan dalam AX, dengan nilai CF=0 DAN OF=0

INTRUKSI DIV DAN IDIV
Intruksi DIV dan IDIV melaksanakan  fungsi pembagian bilangan 8-bit atau 16-bit, bertanda dan tidak bertanda. Terdapat operand tunggal (operand register atau memori), yang di asumsikan sebagai pembagian format sintak DIV dan IDIV sebagai berikut:
            DIV sumber
            IDIV sumber
Jika pembagi panjangnya 8-bit maka nilai yang dibagi diletakan dalam register AX,AL hasil bagi dan AH sisanya. Jika pembagi 16 bit, DX : AX yang akan dibagi maka hasil bagi diletakan dalam register AX dan sisa bagi diletakan dalam register DX.
            Yang dibagi/ pembagi = Hasil bagi sisa
AX                  operand           AL       AH
DX : AX         operand           AX      BX
Contoh 1. Pembagian 8-bit ( 83h/2=41h, sisa 3)
            Mov ax, 0083h            , yang akan dibagi
            Mov bl, 2         ; pembagi
            Div bl              ;AL = 41h dan AH = 01h
Contoh 2. Pembagian 16-bit (8003h/100h = 80h, sisa 3)
DX berisi nilai yang akan dibagi pada posisi tinggi, jadi kita harus menggosongkannya sebelum pembagian. Sesudah pembagian, hasil baginya disimpan dalam register AX dan sisanya dalam register DX:
            Mov dx, 0
            Mov ax, 8003h
            Mov cx, 100h
            Div cx
Contoh 3. pembagian 16-bit menggunakan operand memori sebagai pembagi:
            Mov dx, 0
            Mov ax, dividend
            Div divisor
Dividend         dw       8003h
Divisor                        dw       100h

INTRUKSI IDIV
Intruksi IDIV melaksanakan operasi pembagian bertanda. Untuk pembagian 8-bit, nilai yang akan dibagi diletakkan dalam register AX, jadi tandanya ditentukan oleh bit ke-15. contohnya, kita akan membagi- 48 dengan 5, menghasilkan AL = -9 dan AH = 3
            Mov ax,-48 ;AX = FFD0h
            Mov bl, 5
            Idiv bl
Satu kesalahan umum yang biasa dilakukan adalah meletakan nilai yang akan dibagi dengan memindahkan -48 kedalam AL. jika AH sama dengan 00h maka IDIV akan salah mengasumsikan yang akan dibagi yaitu bernilai + 208 (00D0h).

INTRUKSI CBW (CONVERT BYTE TO WORD)  DAN CDW (CONVERT WORD TO BYTE)
Jika nilai yang akan dibagi dalam AL harus bertanda diperlebar dengan menggunakan register AH maka dapat menggunakan intruksi CBW. Misalkan kita akan membagi operand memori 8-bit dengan 10. intruksi CBW sebaiknya mempersiapkan hasil bagi, mengonversi 80h ke FF80h:
            aByte db – 128
            ……..
            …….
            Mov al,aByte
            Cbw
            Mov bl, 10
            Idiv
Untuk nilai yang akan dibagi 32-bit, CDW memperpanjang tanda AX ke dalam DX:
            Mov ax,-5000
            Cwd
            Mov bx, 256
            Idiv bx

OVERFLOW PEMBAGIAN
Jika operasi pembagian menyebabkan hasil yang terlalu besar dan tidak dapat dimuat pada register hasil bagi maka terjadi kondisi overflow. Kejadian ini akan memicu pemanggilan sistem interrupt 0. Pada beberapa mesin hal ini menyebabkan komputer menjadi hang. Pembagian dengan nol juga akan menghasilkan overflow pembagian. Bahasa tingkat tinggi telah membuat perlindungan untuk mengatasi hal ini, tetapi CPU sendiri tidak melaksanakan pengecekan kesalahan sebelum pembagian.

Salah satu cara untuk mengatasi hal ini adalah dengan memecah nilai yang dibagi 32-bit menjadi dua bagian yang bernilai word. Contoh, jika kita membagi 08010020h dengan 10h, kita akan menghasilan overflow pembagian karena hasil bagi (0801002h) tidak pas untuk AX. Pembagian  mungkin dilakukan  dengan dua tahap, sebagai berikut:
            Mov ax, dividend + 2
            Cwd
            Mov cx, divisor
            Div cx
            Mov bx, ax
            Mov ax, dividend
            Div cx
            Mov remainder, dx
            ……
            ……
            ……
            Dividend         label     word
                                    Dd       08010020h
            Divisor                        dw       10h
            Remainder       dw       ?
Pertama kita membagi word yang paling tinggi yang akan dibagi. Baris 1 dan 2 mengambil nilai yang akan dibagi kedalam AX dan tanda dilebarkan kedalam register DX. Baris 4 membagi bagian lebih tinggi dari nilai yang dibagi (0801h) dengan 10h. Hasil bagi 0080h dan sisanya 0001h:
            0000:0801h / 10h = 0800h, sisa 1
            (DX:AX)                     (CX)    (AX)    (DX)


Tidak ada komentar:

Posting Komentar