Anda di halaman 1dari 0

III.

DASAR-DASAR BAHASA ASSEMBLY


3.1. Perintah Definisi Data
Variabel adalah nama simbolik untuk lokasi dalam memori dimana data disimpan.
Dalam bahasa assembly, variabel diidentifikasikan oleh label. Setiap label
menunjukan lokasi awal variabel. Kita katakan bahwa offset label adalah jarak dari
awal segmen ke awal variabel.
Label, tidak menunjukan berapa banyak byte memori yang dialokasikan untuk
bariabel. Contoh, jika kita mendeklarasikan array 4 karakter, lebel aList hanya
mengidentifikasikan offset karakter awal (A)
Jadi jika huruf awal pada offset 0, maka selanjutnya pada offset 1, 2 dan
seterusnya. Kita menggunakan memori berdasarkan pada tipe yang didefinisikan
sebelumnya :
Deskripsi Byte Atribut
DB Define byte 1 Byte
DW Define word 2 Word
DD Define doubleword 4 Dobleword
DF, DP Define far pointer 6 Far pointer
DQ Define quadword 8 Quadword
DT Define tenbytes 10 Tenbyte
Define byte (DB)
Perintah DB mengalokasikan memori untuk satu atau lebih nilai 8-bit. Diagram
sintak berrikut menunjukan bahwa nama adalah pilihan, dan hanya satu initial value
yang diperlukan. Jika diperlukan lebih dari satu maka dipisahkan dengan koma :
[name] DB initialvalue [, initialvalue]
Initial value dapat berupa satu atau lebih nilai angka 8-bit, konstanta string, ekspresi
konstan atau tanda tanya (?). jika nilai bertanda maka rangenya 128 - + 127, jika
tidak bertanda rengenya 0-255. berikut contohnya :
A B C D
1 2 3 4
Deklarasi
AList db ABCD
Isi
Offset
Disimpan sebagai
char db A
signed1 db -128
signed2 db +127
unsigned1 db 0
unsigned2 db 255
Nilai banyak (multiple values), daftar bilangan-bilangan 8-bit mungkin
dikelompokan dibawah satu label, dengan nilai dipisahkan oleh koma. Pada contoh
berikut, kita umpamakan bahwa daftar disimpan pada offset 0000. Ini artinya bawha
10 disimpan pada offset 0000, 20 pada offset 0001, 30 pada offset 0002, dan 40 pada
offset 0003.
List db 10, 20, 30, 40
Karakter dan integer adalah satu dan sama. Variabel berikut mengandung nilai yang
sama dan mungkin diproses dengan cara yang sama :
char db A
hex db 41h
dec db 65
bin db 01000001b
oct db 101q
Setiap konstanta mungkin menggunakan radix yang berbeda ketika daftar item
didefinisikan, dan angka, karakter dan konstanta string mungkin dicampur secara
bebas. Jika nomor heksadesimal mulai dengan huruf (A-F), maka nol diawal
ditambahkan untuk membedakannya dengan label. Dalam conoh ini, list1 dan list2
mempunyai isi yang sama :
list1 db 10, 32, 41h, 00100010b
list2 db 0Ah, 20h, A, 22h
Isi variabel mungkin tidak didefinisikan, untuk hal seperti ini menggunakan operator
tanda tanya (?). atau ekspresi bilangan dapat memberi nilai awal sebuah variabel
dengan nilai yang dihitung pada saat diassembly. Contoh :
count db ?
ages db ?,?,?,?,?
rowsize db 10*20
Varibel dapat diberi nilai string dimana variabel merupakan alwam byte awal.
Contoh berikut menunjukan satu string diakhiri oleh byte nol (mengandung 0), dan
string lain dengan panjangnya ditulis pada awal byte :
c_string db Good afternoon, 0
pascal_string db 14, Good afternoon
Perintah DB adalah perintah yang digunakan untuk menyimpan satu atau lebih baris
teks. Variabel tunggal mungkin dilanjutkan untuk banyak baris tanpa perlu membuat
label untuk masing-masing baris. String berikut diakhiri oleh akhir baris dan byte
null :
a_long_string db This is a long string, that
db clearly is going to take
db several lines to store in an
db assembly language program, 0Dh, 0Ah, 0
Assembler dapat menghitung panjang string secara otomatis. Dengan menggunakan
karakter $ yang menyimpan lokasi sekarang nilai counter. Pada contoh berikut
a_string_len diset awal 16 :
a_string db This is a string
a_string_len db $- a_string
Define Word (DW)
Perintah DW membuat tempat penyimpan untuk satu atau lebih word 16-bit.
Sintaknya adalah sebagai berikut
[name] DW initialvalue [, initialvalue]
Initialvalue mungin berupa nilai bilangan 16-bit dari 0 65,535 (FFFFh). Jika
initialvalue bertanda, range yang dapat diterima adalah dari 32,768 (8000h) sampai
+32,767 (7FFFh). Konstanta karakter mungkin disimpan pada bagian bawah word.
Kontanta string yang besar yang mungkin disimpan dalam word panjangnya 2
karakter, seperti AB. Mungkin juga membiarkan variabel tidak terinisiaslisasi
dengan menggunakan operator (?).
Pembalikan Format Penyimapan (Reversed Storage Format). Assembler
membalik byte dalam nilai word ketiak disimpan dalam memori. Byte paling bawah
berada pada alamat paling bawah. Ketika variabel dipindahkan ke register 16-bit,
CPU akan membalik kembali byte tersebut. Ini ditunjukan pada ilustrasi berikut,
dimana 2AB6h disimpan dalam memori sebagai B6 2A.
Deklarasi data : value1 dw 2AB6h
Penyimpanan :
B6 2A
Berikut ini tambahan contoh untuk DW. Seperti pada DB, tanda tanya
memerintahkan assembeler untuk tidak menginisialisasi loakasi memori dengan nilai
tertentu :
dw 1, 2, 3 ; mendefinisikan 3 word
dw 0,65535 ; bilangan tidak bertanda tertendah dan tertinggi
dw 32768, +32767 ; bilangan bertanda terendah dan tertinggi
dw 256*2 ; ekspresi kontanta
dw 4000h ; notasi heksadesimal
dw 1111000011110000b ; notasi biner
dw 1000h, 4096, AB, 0 ; notasi campuran
dw ? ; word tunggal tidak diinsialisasi
Pointer. Offset variabel atau subrutin mungkin disimpan dalam variabel lain yang
disebut pointer. Pada contoh berikut, assembler menset P ke offest list. Kemudian PI
mengandung alamat P. Akhirnya, aProc mengandung offset label yang disebut
Clear_screen :
list dw 256, 257, 258, 259
P dw list
P2 dw P
aProc dw clear_screen
Define Doubleword (DD)
Perintah DD membuat tempat penyimpan untuk satu atau lebih doublewords 32-bit.
Sintaknya sebagai berikut :
[name] DD initialvalue [, initialvalue]
Initialvalue dapat berupa nomor biner sampai 0FFFFFFFFh, alamat segmet-offset, 4-
byte bilangan real, atau bilangan real desimal. Byte-byter dalam variabel doubleword
disimpan dengan urutan terbalik, sehingga digit yang paling berarti disimpan pada
alamat paling bawah. Contoh, nilai 12345678h akan disimpan dalam memori sebagai
:
Offset : 00 01 02 03
Nilai : 78 56 34 12
Anda dapat mendefinisikan satu atau leibh doubleword. Dalam contoh berikut,
far_pointer1 tidak diinsialisasi. Assembler langsung menginisialisasi far_pointer2
dengan 32-bit alamat segment offset subroutine1 :
signed_val dd -2147483648
far_pointer1 dd ?
far_pointer2 dd subroutine1
Operator DUP
Operator DUP hanya tampil sessudah perintah pengalokasian memori (DB, DW, DD,
DQ, DT). Dengan DUP, anda dapat mengulang satu atau lebih nilai ketika
mengalokasian memori. Ini khususnya berguna ketika pengalokasian ruang untuk
tabel atau array. Contoh-contoh berikut menginisialisasi tempat penyimpan dengan
nilai default :
db 20 dup (0) ; 20 byte semuanya sama dengan nol
db 20 dup (?) ; 20 byte tidak diinisialisasi
db 4 dup (ABC) ; 12 byte : ABCABCABCABC
db 4096 dup (0) ; 4096-byte , semuanya nol
dw 5 dup (1000h) ; 5 word, masing-masing sama dengan nol
dw 5 dup (?) ; 5 word, tidak diinisialisasi
dd 100h dup(?) ; 256 doublewordk (1024 byte)
Operator DUP mungkin juga bersarang. Contoh pertama yang membuat tempat
penyimpan yang mengandung 000XX000XX000XX000XX. Contoh kedua membuat
tabel word dua dimensi dengan 3 baris dan 4 kolom.
aTable db 4 dup ( 3 dup(0), 2 dup(X))
aMatrix dw 3 dup (4 dup(0))
Pemeriksaan tipe. Ketika variabel dibuat dengan menggunakan DB, DW, DD atau
perintah definisi data yang lain, assembler memberinya atribut asal (byte, word,
doubleword) berdasarkan ukurnya. Tipe ini dicek ketika anda merujuk pada variabel
tersebut, dan akan terjadi kesalahan jika tipenya tidak sesuai. Contohnya, anda ingin
memindahkan byte paling rendah varibel 16-bit ke dalam register 8-bit. Instruksi
MOV berikut akan salah karena count bertipe word dan AL adalah byte :
mov al, count ; error : ukuran operand harus cocok

.
count dw 20h
Pemeriksaan tipe seperti itu bagus karena membantu untuk menghindari kesalahan
logika. Jika diperlukan anda dapat menggunakan perintah LABEL untuk membuat
nama baru (dan tipe data) pada alamat yang sama. Sekarang variabel dapat diakses
menggunakan nama juga :
mov al, count_low
mov cx, count

count_low label byte


count dw 20h
3.2. Instruksi Transfer Data
Instruksi MOV
Karena MOV menyalin data dari satu operand ke operand lain, maka ini disebut
instruksi transfer data. Pada prosesor 8086 dan 80286, operandnya 8 atau 16 bit.
Pada 80386 dan 80486, operand 32-bit juga mungkin digunakan. Sintaknya sebagai
berikut :
MOV tujuan, sumber
Data benar-benar disalin sehingga operand sumber tidak berubah. Sumber
mungkin berupa nilai, register, atau operand memori. Tujuan mungkin berupa nilai,
register atau operand memori. Tujuan mungkin berupa register atau operand memori.
Operand Register. Pemindahan hanya melibatkan register, ini paling efisien. Satu
register berperan sebagai operand sumber, dan yang lainya, selain CS dan IP
berperan sebagai operand tujuan.
Operand immediate. Nilai langsung (konstanta integer) mungkin dipindahkan ke
suatu register (kecuali register segemen atau IP) dan mungkin dipindahkan ke
memori. Kesalahan umum disebabkan nilai lebih besar daripada operand tujuan.
Operand langsung. Variabel mungkin salah satu (tapi tidak keduanya) operand
dalam instruksi MOV. Isi variabel mungkin sumber atau tujuan move.
Contoh MOV dengan semua tiga tipe seperti berikut :
mov al, bl
mov dx, cx
mov bl, 1
mov bx, 8FE2h
mov al, count
mov total, ax
mov total, 1000h


count db 10
total dw 0
Operand mempunyai sedikit keterbatasan, yang berdasarkan rancangan fisik
pemroses dan set instruksinya. Berikut ini tidak diperbolehkan :
- CS atau IP sebagai register tujuan
- Memindahkan data immediate ke register segmen
- Memindahkan dari register segmen ke register segmen
- Perbedaan ukuran antara operand sumber dan tujuan
- Nilai immediate sebagai tujuan
- Perpinadahan dari memori ke memori
Contoh pemindahan yang tidak diperbolehkan :

mov ip, ax ; ip sebagai tujuan
mov ds, 1000h ; immediate ke segmen
mov ds, es ; segmen ke segmen
mov al, bx ; ukuran operan tidak sama
mov si, al ; ukuran operan tidak sama
mov word_1, al ; ukuran operan tidak sama
mov 1000h, ax ; immediate sebagai tujuan
mov word_2, word_1 ; memori ke memori

word_1 dw 1000h
word_2 dw 0
Offset
Anda dapat menambahkan offset pada operand memori. Dengan ini maka anda dapat
mengakses nilai data yang tidak mempunyai label. Misalkan kita punya daftar nomor
8-bit yang disebut array. Kemudian array+1 adalah nama yang mengacu pada offset
1 byte lebih dari array. Keduanya, array dan array+1 mempunyai offset yang
dihitung oleh assembler sebagai offset fixed dari permulaan segemen data. Alamat-
alamat tersebut digunakan untuk mengakses memori pada offset yang diberikan,
seperti contoh berikut :
. data
array db 10, 20, 30, 40, 50
. code
mov al, array ; isi = 10
mov dl, array+1 ; isi = 20
mov dh, array+4 ; isi = 50
Ukuran atribut kedua operand harus sesuai. Dalam contoh berikut, int_1 hanya dapat
dipasangkan dengan register 16-bit. Juga, byte_1 hanya dapat dipasangkan dengan
register 8-bit :
. data
int_1 dw 1000h
byte_1 db 10h
. code
mov ax, int_1
mov int_1, si
mov al, byte_1
mov byte_1, dl
Operator PTR. Biasanya kita menggunakan operator PTR untuk mengetahui tipe
operand. Nama PTR tidak benar kalau dimaksudkan penggunaan pointer ini
bernar-benar mengidentifikasikan atribut operand memori. Pada contoh berikut,
WORD PTR mengidentifikasikan count sebagai variabel berukuran word, dimana
BYTE PTR mengidentifikasikan var2 sebagai operand 8-bit.
mov word ptr count, 10
mov byte ptr var2, 5
Perintah XCHG
Perintah XCHG menukarkan isi dari dua register atau antara register dengan
variabel. Sintaknya sebagai berikut :
XCHG op1, op2
Dua operand mungkin register atau operand memori, selama satu operandnya
register.
XCHG adalah cara yang efisien untuk menukarkan dua operand 8-bit atau 16-bit
karena tidak memerlukan register ketiga untuk menyimpan nilai sementara.
Khususnya dalam aplikasi pengurutan, instruksi ini mempunyai keuntungan karena
kecepatannya. Satu atau kedua operand mungkin register, atau register mungkin
dikombinasikan denan operand memori. Dua operand memori tidak boleh digunakan
secara bersamaan. Contoh berikut adalah contoh yang benar :
xchg ax, bx
xchg ah, al
xchg var1, bx
Operasi stack
Stack adalah buffer memori khusus yug digunakan untuk program aplikasi dan
DOS. Dua register berperan dalam stack : register SS (stack segment) mengandung
lokasi basis stack; register SP (stack pointer) mengandung alamat puncak stack,
dimana nilai terakhir dimasukan.
Beberapa istilah yang terdapat pada stack : operasi PUSH adalah meletakan nilai
baru pada stack dan mengurangi nilai stack pointer; stack bergerak kearah bawah
dalam memori setiap nilai baru dimasukan. Operai POP mengeluarkan data dari
stack dengan menyalin words kedalam register atau operand memori dan menambah
nilai stack pointer. Setiap inputan stack panjangnya 2 byte, jadi hanya operand 16-bit
yang mungkin dimasukan atau dikeluarkan.
DOS membagi stack dengan program aplikasi, jadi ruang memori yang cukup
harus disiapkan untuk menyediakan keduanya. Biasanya kita menggunakan 256 byte,
menggunakan perintah .STACK.
Instruksi PUSH. Instruksi PUSH mengurangi register SP dan menyalin isi register
atau operand memori 16-bit kedalam stack pada lokasi yang ditunjuk oleh SP. Hanya
pada prosesor 80286 atau yang lebih tinggi anda dapat memasukan nilai immediate.
Berikut ini contoh penggunaanya :
push ax
push memval
push 1000h
Instruksi PUSH bisa digunakan untuk menyimpan nilai register sementara, untuk
suatu saat diambil kembali.
Instruksi POP. Instruksi POP menyalin isi stack yang ditunjukan oleh SP ke dalam
register 16-bit atau variabel, dan menambah SP. Dua register, CS dan IP, tidak boleh
digunakan sebagai operand. Contoh POP seperti terlihat dibawah ini.
pop cx
pop memval
Menyiman dan mengambil kembali nilai register. Berbagai cara bisa dilakukan jika
sebuah register akan digunakan ulang. Pada contoh berikut, pemanggilan DOS (int
21h) untuk menampilkan string pada layar. DX dan AX diasumsikan mempunyai
nilai penting yang harus disimpan kembali sesudah tampilan. Karena stack
berstruktur LIFO (last in first out) maka register yang terakhir disimpan pertama kali
:
push ax
push dx
mov ah, 9
mov dx offset message
int 21h
pop dx
pop ax


message db Ini adalah pesan.$
PUSHF dan POPF. Instruksi PSUHF memasukan register flag ke dalam stack,
menjaganya agar tidak terjadi perubahan. Pada lain waktu, instruksi POPF dapat
digunakan untuk mengembalikan nilai flag. Contoh berikut, kita menyimpan flag
sebelum memanggil subrutin yang mungkin mengubah flag.
3.3. Instruksi Aritmetik
Hampir semua program komputer dapat melaksanaklan operasi aritmetik. Set
intruksi Intel mempunyai instruksi untuk aritmetik integer, menggunakan operand 8-
bit dan 16-bit. Operasi floating-point ditangani dalam salah satu dari ketiga cara
berikut : 1. Chip koprosesor matematika khusus (8087, 80287, 80387). 2. Rutin
perangkat lunak yang berfungsi sama dengan koprosesor, atau 3. Perangkat lunak
yang mengkonversi nilai floating-point ke integer, menghitung, dan kemudian
mengkonversi bilangan kembali ke floating-point.
Instruksi INC dan DEC
Instruksi INC dan DEC menambah 1 atau mengurang 1 nilai dari suatu operand,
secara berurutan. Sintaknya sebagai berikut :
INC tujuan
DEC tujuan
Tujuan mungkin register 8-bit atau 16-bit atau operand memori. INC dan DEC
lebih cepat dari instruksi ADD dan SUB. Semua status flag dipengaruhi kecuali flag
Carry. Contohnya sebagai berikut :
inc al
dec bx
inc membyte
dec byte ptr membyte
dec memword
inc word ptr memword
Instruksi ADD
Instruksi ADD menjumlahkan operand sumber 8 atau 16-bit ke operand tujuan
pada ukuran yang sama. Sintaknya sebagai berikut :
ADD tujuan, sumber
Sumber tidak diubah oleh operasi. Ukuran operand harus sesuai dan hanya satu
operand memori yang digunakan. Register segment tidak boleh jadi tujuan. Semua
status flag dipengaruhi. Contoh sebagai berikut :
add al, 1
add cl, al
add bx, 1000h
add var1, ax
add dx, var1
add var1, 10
Instruksi SUB
Instruksi SUB mengurangkan operad sumber dari operand tujuan. Sintak SUB
sebagai berikut :
SUB tujuan, sumber
Ukuran kedua operand harus sesuai, dan hanya boleh satu operand memori.
Register segment tidak boleh jadi operand tujuan. Pada level bit, yang terjadi adalah
operand source dinegasikan kemudian ditambahkan ke tujuan. Contoh, 4-1 adalah
4+(-1). Mengingat kembali bahwa notasi twos komplemen digunakan untuk
menegasikan bilangan, jadi 1 disimban sebagai 11111111b :
0 0 0 0 0 1 0 0 (4)
+ 1 1 1 1 1 1 1 1 (-1)
0 0 0 0 0 0 1 1 (3)
Penjumlahan ini menghasilkan carry pada bit yang paling tinggi (menset carry
flag), tetapi carry sendiri diabaikan ketika bekerja dengan bilangan bertanda.
Contoh SUB digunakan denganb berbagai tipe operand seperti berikut :
sub al, 1
sub cl, al
sub bx, 1000h
sub var1, ax
sub dx, var1
sub var1, 10
Flag yang dipengaruhi oleh ADD dan SUB
Jika ADD atau SUB menghasilkan nilai nol, maka flag zero di set; jika hasil
negatif maka flag tanda di set. Pada contoh beirkut, baris 2 menghasilkan nilai nol
dan baris 4 menghasilkan nilai 1 (FFFFh) .
mov ax, 10
sub ax, 10
mov bx, 1
sub bx, 2
Flag zero diset ketika hasil operasi aritmetik sama dengan nol. Catatan bahwa
INC dan DEC mempengaruhi flag zero tapi tidak mempengaruhi flag carry :
mov bl, 4Fh
add bl, 0B1h
mov ax, 0FFFFh
inc ax
Keputusan kapan operand bertanda atau tidak bertanda seluruhnya diserahkan
kepada pemrogram. CPU memperbaharui flag Carry dan overflow untuk menangani
dua kemungkinan. Untuk alasan ini, kita perlu membahas dua tipe operasi secara
terpisah.
Operasi tidak bertanda (unsigned). Untuk aritmetika tidak bertanda, kita hanya
peduli pada flag carry. Jika hasil operasi penjumlahan terlalu besar untuk operand
tujuan, maka flag carry diset. Contoh, penjumlahan 0FFh + 1 seharusnya sama
dengan 100h, tapi hanya dua digit paling bawah (00) yang pas untuk AL. maka
operasi menset flag carry :
mov ax, 00FFh
add al, 1 ; AX = 0000, CF = 1
Dalam kontek ini, ADD adalah operasi 8-bit karena AL yang digunakan. Jika kita
ingin mendapatkan jawaban yang benar maka kita harus menambah 1 AX,
membuatnya menjadi operasi 16-bit.
mov ax, 00FFh
add ax, 1 ; AX = 0100, CF = 0
Situasai yang sama juga terjadi ketika kita mengurangkan operand yang lebih
besar (2) kepada yang lebih kecil (1). Flag carry memberitahu kita hasilnya tidak
berguna.
mov ax, 5501h
add ax, 2 ; AX = 55FF, CF = 1
Operasi bertanda. Flag overflow diset ketika operasi penjumlahan atau pengurangan
menghasilakan bilangan bertanda diluar range.
Contoh 1 :
mov al, + 126 01111110
add al, 2 + 00000010
10000000 AL = -128 ?, OF =1
Contoh 2 :
mov al, -128 10000000
sub al, 2 - 00000010
01111110 AL = + 126?, OF = 1
3.4. Mode Pengalamatan
Kumpulan instruksi Intel menyediakan cara yang bervariasi untuk menemukan
lokasi memori cara-cara ini disebut mode pengalamatan. Dengan cara ini dapat
memudahkan pemrosesan list dan untuk mengacu struktur data yang komplek. Juga,
kompile bahasa tingkat tinggi memerlukannya untuk membuat instruksi mesin yang
lebih sedikit ketika set instruksi CPU menggunakan cara yang baik dalam pengacuan
data.
Terdapat lima tipe mode pengalamatan, ditunujukan dalam tabel mode
pengalamatan dibawah. Dalam tabel, dispalecement berupa angka atau offset
variabel. Effective address operand mengacu pada offset (jarak) data dari awal
segment. BX dan BP adalah register basis, dan SI dan DI adalah register index.
Setiap contoh berikut mengacu pada isi memori pada alamat efektif.
Mode pengalamatan
Mode Contoh Keterangan
Direct Op1
bytelist
[200]
Alamat efektif adalah
displacement
Register Indirect [bx]
[si]
[di]
EA adalah isi basis atau
index
Based or Indexed list [bx]
[si+list]
[bp+4]
list [di]
[bp-2]
EA adalah penjumlahan
register basis atau index
dengan displacement
Base-indexed [bx + si]
[bx][di]
[bp-di]
EA adalah penjumlahan
register basis dan register
index
Base-indexed with
displacement
[bx+si+2]
list[bx+si]
list [bx][si]
EA adalah penjumlahan
register basis, register
index dan dispalcement
Operand register
Operand register mungkin berupa register 8 atau 16 bit. Secara umum, mode
pengalamatan register adalah paling efisien karena register adalah bagian dari CPU
dan tidak diperlukan pengaksesan memori. Beberap contoh menggunakan instruksi
MOV sebagai berikut :
mov ax, bx
mov cl, al
mov si, ax
Operand Immediate
Operand immediate adalah ekspresi konstan, seperti angka, karakter atau ekspresi
aritemetik. Assembler harus menentukan nilai operand immediate pada waktu
asssembly. Nilainya disisiplak langsung kedalam instruksi mesin. Contoh operand
immediate ditunjukan sebagai berikut. Contoh terkahir, (2+3)/5, adalah ekspresi yang
dievaluasi apda saat assembly.
Contoh Ukruan (bit)
10
A
AB
65535
(2+3)/5
8
8
16
16
8
Operand direct
Operand direct mengacu pada isi memori pada offset variabel. Assembler
menjaga nilai offset setiap label, membuatnya memungkinkan untuk menghitung
alamat efektif operand direct. Pada contoh ini, isi memori pada lokasi count dipindah
ke AL :
count db 20


mov al, count ; AL = 20
Oprator OFFSET. Ketika diperlukan pemindahan offset label ke dalam register
atau variabel, maka digunakan operator OFFSET. Karena assembler mengetahuai
offset settiap label sebagai program yang sedang diassembly, maka mudah untuk
menggantikan nilai offset kedalam isntruksi. Misalkan offset variabelaWord dalam
contoh berikut adalah 0200h; instruksi MOV akan memindahkan 200h ke dalam BX
langsung :
aWord dw 1234

mov bx, offset aWord
Operand tidak langsung
Jika offset variabel ditempatkan dalam register basis atau index, maka register
menjadi pointer ke label. Untuk variabel yang mengandung element tunggal, maka
dia akan mempunyai nilai yang kecil, tetapi untuk daftar item, pointer mungkin akan
ditambah untuk menunjuk setiap elemen.
Contoh, jika kita membuat string dalam memori pada lokasi 0200h dan menset
BX ke offset string, kita dapat memproses elemen dalam string dengan
menjumlahkan offsetnya dengan BX. F terakhir berada pada offset 5 dalam contoh
berikut :
CODE :
aString db ABCDEFG

mov bx, offset aString ; BX = 0200


add bx, 5 ; BX = 0205
mov dl, [bx] ; DL = F
Ilustrasi
0200
aString [bx]
Default segmen. Jika BX, SI atau DI digunakan, alamat efektif adalah default
offset dari register DS (data segment). BP, disisi lain, merupakan offset dari register
SS (Stack segment). Umpamanya segment stack dan segment data berada pada lokasi
yang berbeda, dua pernyataan berikut akan menimbulkan efek yang berbeda :
mov dl, [si]
mov dl, [bp]
Based dan Indexed Operand
Operannd basis dan indeks pada dasarnya sama : register ditambahkan pada
displacement untuk mendapatkan alamat efektif. Register yang dipakai harus SI, DI,
BX atau BP. Displacement adalah angka atau label yang offsetnya diketahui pada
waktu assembly. Notasi mungkin dalam bentuk yang sama :
Register ditambahkan ke offset :
mov dx, array[bx]
mov dx, [di+array]
mov dx, [array+si]
Register ditambahkan ke konstanta :
mov ax, [bp+2]
mov dl, [di-2]
mov dx, 2[si]
A B C D E F G
Contoh. Jika kita membuat array bernilai byte yang disimpan dal memori logaksi
0200h dan menset BX dengan 5, maka BX akan menunjuk bialngan pada offset 5 ke
dalam array. Contoh berikut ini sebagai ilustrasi :
Code :
array db 2,16,4,22,13,19,42,64,44,88

mov bx, 5
mov al, array[bx]
ilustrasi :
array [BX] (BX = 0005)
Base-Indexed Operand
Alamat efektif operand dibangun oleh penggabungan register basis dengan
register index. Misalkan BX = 2002h dan SI = 6; instruksi berikut akan menghitung
alamat efektif 208h :
mov al, [bx +si]
Teknik ini sering berguna untuk array dua dimensi, dimana BX dapat menunjuk
offset baris dan SI offset kolom. Contoh berikut, alamat efektif yang dibangun oleh
[bx+si] adalah 0157 :
CODE :
array db 10, 20, 30, 40, 50
db 60, 70, 80, 90, A0
db B0, C0, D0, E0, F0
.
mov bx, offset array ; menunjuk pada array (0150)
add bx, 5 ; memilih baris kedua
mov si, 2 ; memilih kolom ke tiga
mov al, [bx + si] ; mengambil nilai pada alamat efektif 0157
Ilustrasi
0150
02 16 04 22 13 19 42
10 20 30 40 50 60 70 80 90
[BX] [SI]
Dua buah register basis atau dua buah register index tidak dapat digabungkan, jadi
contoh berikut akan salah :
mov dl, [bp-bx] ; salah : dua register basis
mov ax, [si-di] ; salah : dua register index
Base-Indexed dengan displacement
Alamat efektif operand dibangun dengan menggabungkan register basis, register
index dan displacement. Contohnya sebagai berikut :
mov dx, array [bx] [si]
mov ax, [bx + si + array]
add dl, [bx + si + 3]
sub cx, array [bp+si]
Dengan menggunakan array dua dimensi kita tidak harus lagi menset BX ke awal
array. Kita hanya menset BX pada offset baris kedua, relatif terhadap awal tabel. Ini
akan menyebabkan kode lebih sederhana :
CODE :
array db 10, 20, 30, 40, 50
db 60, 70, 80, 90, A0
db B0, C0, D0, E0, F0
.
mov bx, 5 ; memilih baris kedua
mov si, 2 ; memilih kolom ke tiga
mov al, array[bx + si] ; mengambil nilai pada alamat efektif 0157
Ilustrasi
0150 0155 0157
[BX] [SI]
10 20 30 40 50 60 70 80 90
Penjumlahan serangkaian bilangan
Contoh program berikut menunjukan bagaimana bermacam-macam mode
pengalamatan bisa digunakan ketika mengakses elemen sebuah array. Array berada
pada offset 150, dan hasil penjumlahan akan disimpan pada offset 153. Program
berikut mungkin diassemble dan dijanlankan dalam Debug.
A 150
db 10, 20, 30, 0
A 100
mov bx, 150
mov si, 2
mov al, [bx]
add al, [bx+1]
add al, [bx + si]
mov [153], al
int 20
t
.
.
d 150, 153
3.5. Struktur Program
Gambar 3.1. menunjukan program HELLO.ASM. Perintah untuk mengassembly
dan link program ini ditunjukan oleh turbo assembler dan microsoft assembler
sebagai berikut :
Turbo Assembler MASM
tasm hello; masm hello;
tlink hello; link hello;
Segment. Program yang jalan di DOS dibagi kedalam tiga segmen utama, masing-
masingnya memiliki nilai tipe yang berbeda : segmen Code (ditunjukan oleh CS)
mengandung kode program, segmen Data (ditunjukan oleh DS) mengandung
variabel, segmen stack (ditunjukan oleh SS) mengandung stack program.
Setiap segmen ditunjukan oleh register segmen. Sebuah segmen mungkin hanya 1
paragraf (10h byte) dan paling besar 64 K bytes. Setiap segmen mengandung
instruksi atau data yang memiliki offset relatif terhadap register segmen (CS, DS, SS,
atau ES). Offset adalah jarak objek dari permulaan segmennya.
Title Program Hello world [1]
[2]
; program ini menampilkan pesan Hello, world [3]
[4]
dosseg [5]
. model small [6]
. stack 100h [7]
[8]
. data [9]
. hello_message db Hello, world !, 0dh, 0ah, $ [10]
[11]
. code [12]
main proc [13]
mov ax, @data [14]
mov ds, ax [15]
[16]
mov ah, 9 [17]
mov dx, offset hello_message [18]
int 21h [19]
[20]
mov ax, 4000h [21]
int 21h [22]
main endp [23]
endp main [24]
Gambar 3.1. Contoh program Hello
Segmen code. Segmen code adalah dimana instruksi mesin program berada.
Register CS mengandung alamat segmennya, dan IP menunjuk instruksi pertama
yang akan dieksekusi. Segmen data baisanya mengandung variabel program. Catatan
bahwa tidak ada register yang menunjukan segmen ini, karena itu pada setiap
program EXE dimasukan baris program berikut, untuk menset DS sebagai permulaan
segmen data :
mov ax, @data
mov ds, ax
Segmen stack. Asegmen stack mengaikuti .MODEL, dan biasanya kita menyediakan
256 byte ruang stack. Register SS mengandung alamat segmen ini, dan SP mengacu
pada alamat berikutnya setalah akhir stack. Stack akan bertambah kearah bawah pada
saat suatu nilai dimasukan ke dalam stack. Jika SP mencapai 0000, maka stack
berarti penuh.
Perintah. Perintah TITLE mendefinisikan judul prgram sampai 128 karakter.
Perintah DOSSEG memberitahu assembler untuk menempatkan segmen program
dalam urutan standar yang digunakan bahasa tingkat tinggi.
Model memori
Perintah .MODEL memilih standar model memori untuk program bahasa
assembly. Model memory mungkin sebagai blueprint standar atau konfigurasi, yang
menentukan bagaimana segmen dihubungkan bersama. Setiap model memori
memiliki sekumpulan batasan yang berbeda sebagai maksimum ruang yang tersedia
untuk kode dan data.
Secara umum, pemilihan model memori berarti membuat pilihan antara kecepatan
eksekusi optimal dan fleksibilitas ukuran program. Model memori yang membatasi
semua data ke segmen tunggal 64 K, contohnya, menjamin bahwa semua alamat data
akan dekat, yaitu, 16-bit nilai. Data mungkin dapat diakses lebih cepat, karena alamat
16-bit mungkin diload dengan satu instruksi mesin. Disisi lain, model memori yang
mengijinkan kode untuk diperluas sampai 64 K berakibat bahwa beberapa subrutin
akan berada pada segmen yang berbeda. Ini berarti bahwa alamat 32-bit harus diload
kedalam CS dan register IP ketika subrutin dipanggil. Hal ini membutuhkan dua
instruksi mesin.
Berbagai macam memori model didefinisikan oleh jumlah byte yang digunkan
untuk kode (instruksi) dan data (variabel). Tabel berikut menunjukan rangkuman
perbedaan antara berbagai tipe model :
Model Penjelasan
Tiny
Small
Medium
Compact
Large
Huge
Kode dan data digabung harus <= 64 K
Kode <= 64 K, data <= 64 K
Data <= 64 K, kode ukuran sembarang
Kode <=64 K, data ukuran sembarang
Keduanya lebih besar dari 64 K
Sama seperti model LARGE hanya array boleh lebih dari 64 K
Semua model keculai model Tiny menghasilkan program EXE. Model Tiny
menghasilkan program COM.
Peta file program Hello :
Start Stop Length Name Class
00000H 00010H 00011H _TEXT CODE
00020H 0002FH 00010H _DATA DATA
00030H 0012FH 00100H STACK STACK
Diagram segmen :
Misalkan program diload pada alamat absolut 20000 :
Segmen Alamat Absolut Nilai Register Segmen
Code 20000 2000
(20h byte)
Gambar 3.2. Struktur segmen Hello.exe
Program yang dapat dieksekusi (Executable program). Untuk mendapatkan
gambaran yang lebih baik tentang program yang dapat dieksekusi setelah diisikan
oleh DOS ke dalam memori, lihatlah gambar 3.2. yaitu prgram HELLO.ASM, yang
diassemble dan dilink ke bentuk HELLO.EXE. Linker dapat menghasilkan file MAP,
yang dengan baik menunjukan offset dan ukuran segmen program. Dalam contoh ini,
segmen kode adalah 11h bytee, segemen datanya 10h byte, dan panjang stacknya
100h byte.
Data 20020 2002
(10h byte)
Stack 20030 2003
(100h byte)