You are on page 1of 120

PEMROGRAMAN BAHASA RAKITAN

DIKTAT KULIAH

Oleh: Hendra, MT. Hartono, M.Kom.

PROGRAM STUDI TEKNIK INFORMASI STMIK IBBI MEDAN 2012

Kata Pengantar
Bahasa mesin adalah bahasa yang yang menjadi bagian dari mikroprocessesor, dan dapat dieksekusi tanpa membutuhkan proses Assembler maupun Compiler, tetapi sesuatu hal yang menjadi masalah adalah bahasa mesin cenderung rumit, karena menggunakan bilangan biner sebagai representasi dari perintah-perintah. Pada perkembangan selanjutnya dikembangkan mnemonic yang melambangkan dari masing-masing instruksi bahasa mesin yang dikenal sebagai bahasa rakitan (Assembly), dan membutuhkan satu tahapan assembler untuk mengubah mnemonic menjadi bahasa mesin. Mempelajari bahasa mesin merupakan salah satu mata kuliah yang wajib dikuasai oleh oleh mahasiswa jurusan teknik informatika, walaupun dewasa ini adalah kurang relevan untuk memprogram suatu program dengan bahasa rakitan, tetapi penguasaan bahasa rakitan akan memberikan keunggulan tersendiri, terutama ketika kita ingin mengoptimalkan bagian tertentu dari program kita, mengakses ke perangkat keras, melakukan reversed engineering untuk mempelajari dan memperbaiki suatu software dimana source tidak tersedia. Penguasaan teknik pemrograman bahasa rakitan memberikan pengetahuan yang lebih kepada mahasiswa untuk melangkah kepada pemrograman kernel maupun device driver, karena pemrograman pada tingkat ini membutuhkan banyak akses langsung ke memori maupun perintah primitif API yang disediakan oleh sistim operasi maupun BIOS. Walaupun buku ini tidak membahas tentang pemrograman kernel maupun device driver, tetapi saya yakin dapat menjadi landasan bagi mahasiswa untuk mengembangkan diri kearah sana, karena berbagai referensi telah tersedia diinternet. Medan, 20 Februari 2012 Penulis

Daftar Isi

Bagian 1, Pengenalan Bahasa Mesin............................................................................1 Bagian 2, Pemrograman 8086.......................................................................................7 Bagian 3, Bahasa Rakitan x86....................................................................................16 Bagian 4, Interrupt dan Pemakiannya.........................................................................19 Bagian 5, Memori dan Pengalamatan.........................................................................27 Bagian 6, Percabangan................................................................................................35 Bagian 7, Perulangan..................................................................................................39 Bagian 8, Operasi Logika...........................................................................................43 Bagian 9, Operasi String.............................................................................................50 Bagian 10, Operasi Shift dan Rotasi...........................................................................57 Bagian 11, Operasi Aritmatika....................................................................................64 Bagian 12, Makro.......................................................................................................69 Bagian 13, Sub Rutin..................................................................................................76 Bagian 14, Parameter pada Sub Rutin........................................................................82 Bagian 15, Penanganan I/O........................................................................................85 DAFTAR PUSTAKA.................................................................................................96 LAMPIRAN A. 8086 Mnemonic.....................................................................................................97 B. Tabel ASCII..........................................................................................................105 C. Binary ke Hexadesimal........................................................................................106 D. Menghubungan ASM dengan Pascal...................................................................107 E. Build-in ASM pada Turbo Pascal.........................................................................110 F. Menghubungan Turbo C/C++ dengan Assembly..................................................112 G. Build-in ASM pada Turbo C................................................................................115

Pemrograman Bahasa Rakitan

Bab1, Pengenalan Bahasa Mesin


Apa itu bahasa Mesin
Setiap jenis CPU memiliki bahasa mesin-nya masing-masing. Instruksi bahasa mesin dinyatakan dalam bilangan numeric (Binari) yang tersimpan sebagai byte dimemori. Masing-masing instruksi memiliki kode numerik yang unik yang disebut sebagai operation code atau opcode. Setiap perintah diawali dengan suatu opcode dan dapat diikuti oleh data (lihat lampiran A).

Apa itu bahasa Assembly


Karena Bahasa Mesin sangat rumit untuk diprogram secara langsung (karena berupa bilangan numeric), sehingga dibuat suatu symbol pelambang (mnemonic) untuk mewakili masing-masing instruksi tersebut yang lebih mudah diingat dan dibaca oleh manusia (bayangkan apakah anda lebih mudah mengingat nama teman anda atau nomor telepon rumahnya?).

Apa itu Assembler


Sebagaimana dijelaskan sebelumnya bahwa bahasa Assembly menggunakan mnemonic sebagai penganti bagi instruksi bahasa Mesin, sehingga program yang ditulis dalam bahasa Assembly tidak dapat secara langsung dieksekusi oleh CPU. Dalam hal ini Assembler berperan untuk menterjemahkan mnemonic tersebut menjadi bahasa Mesin yang dapat dieksekusi oleh CPU. Untuk melakukan assembler dapat menggunakan program DEBUG.EXE maupu berbagai aplikasi compiler seperti TASM, MASM, NASM, FASM maupun emulator8086.

Apa itu disassembler


Jika proses Assembler menterjemahkan program yang ditulis dengan bahasa Assembly menjadi bahasa mesin, maka proses disassembler adalah mengembalikan suatu binary program menjadi (mnemonic) bahasa Assembly. Tujuan dari disassembler adalah untuk keperluaan reversed engineering, dimana kita mempelajari maupun memperbaiki suatu software tanpa memiliki source code, misalnya untuk mempelajari teknik penyerangan suatu program malware untuk dibuat anti malwarenya, ataupun memeriksa kemungkinan suatu program terdapat payload.

Mengapa belajar Assembly


Dewasa ini adalah tidak relevan lagi membuat buat suatu program yang secara keseluruhan ditulis dengan bahasa assembly. Assembly biasanya digunakan untuk rutinrutin penting tertentu. Mengapa? Karena adalah lebih mudah memprogram dengan Hendra, MT. & Hartono, M.Kom. 1

Pemrograman Bahasa Rakitan menggunakan bahasa tingkat tinggi dari pada menggunakan assembly. Pemakaian assembly akan mengakibatkan program sulit untuk dialihkan ke platform yang berbeda (ingat bahwa masing-masing CPU memiliki bahasa Mesin yang berbeda), dan berikut ini adalah alasan mengapa anda mempelajari bahasa Assembly : 1. Program yang ditulis dengan assembly akan lebih cepat dan lebih kecil dibandingkan dengan kode yang dihasilkan dengan menggunakan compiler. 2. Assembly memungkinkan akses langsung ke fasilitas system hardware yang mungkin tidak dapat dilakukan dengan menggunakan bahasa tingkat tinggi (membaca/menulis data langsung ke sector, memformat harddisk). 3. Mempelajari assembly akan membantu pengertian yang lebih mendalam bagaimana computer bekerja. 4. Mempelajari pemrograman assembly akan membantu pengertian yang lebih baik tentang bagaimana compiler dan bahasa tingkat tinggi seperti C bekerja. 5. Dengan mengerti bahasa Assembly anda dapat melakukan proses disassembly untuk menganalisa program tertentu.

Latihan :
Topik: Memahami bahasa mesin dan bahasa assembly, serta register dengan program Debug.Exe
Debug merupakan program yang tersedia sejak DOS untuk IBM PC, utility ini cukup bermanfaat dan merupakan suatu keharusan bagi programmer assembler. Debug bekerja pada level bahasa mesin, dan memiliki kemampuan disassembler serta melakukan assembler instruksi (mnemonic) secara langsung ke bahasa mesin.

Mempersiapkan lingkungan praktek


Karena komputer LAB digunakan bersama oleh mahasiswa, maka perlu dipersiapkan folder untuk penyimpanan file praktek anda. Buatlah sebuah folder di Drive E: dengan nama folder menggunakan nim anda, dan kemudian didalam folder tersebut buatlah folder tambahan dengan nama ASM Sehingga menjadi E:\920403024\ASM

Mengaktifkan program Debug


1. Aktifkan MS-DOS Prompt (Start, All Programs, Command Prompt 2. Ubah keaktifkan ke folder anda C:\> E: Hendra, MT. & Hartono, M.Kom. 2

Pemrograman Bahasa Rakitan E:\> CD \920403024\ASM E:\920403024\ASM> 3. Ketikan perintah Debug.exe untuk mengaktifkan program Debug E:\920403024\ASM>Debug.exe

Tanda keaktifan program Debug


Tanda keaktifan anda dalam program Debug ditandai dengan sebuah prompt (-), pada tanda prompt inilah anda mengetikan perintah debug.

Menampilkan tanggal BIOS Revision


Pada computer IBM PC Compatible menyimpan BIOS Revision Date pada alamat FFFF:0005, sehingga anda dapat menggunakan perintah D (Display untuk menampilkan isi pada alamat tersebut diatas. Pada tanda prompt (-) ketikan D FFFF:0005
-d FFFF:0005 FFFF:0000 FFFF:0010 34 FFFF:0020 00 FFFF:0030 70 FFFF:0040 E2 FFFF:0050 12 FFFF:0060 8B FFFF:0070 4F FFFF:0080 98 30 00 00 30 51 00 00 14 36 00 00 00 52 8B 26 97 2F-31 00-00 00-00 BF-7F 57-55 44-02 8A-47 26-8A 32 00 00 01 1E A2 01 47 2F 00 00 B9 06 22 26 02 30 00 00 02 53 00 8A 2E 38 00 00 00 8B 88 67 3A 00 00 00 AB EC 26 0D 04 FC 00 00 47 8B 08 26 73 00 00 00 47 76 01 8B 2C 06/12/08... 4............... ................ p....0........GG ...VPQRWU..S...v ....0..D.."..&.. .4....&.G.&.g.&. O.&.W..&.G..:.s, .....

12 00 00 FB 2E 34 12 D1

00 00 2E CB 8E C4 26 E0

00 00 8E 56 1E 1E 8B 03

00 00 06 50 30 18 57 F0

Pada gambar diatas dapat dijelaskan bahwa pada sisi kiri ditampilkan alamat dari memori yang ditampilkan dalam format Segment (FFFF) dan Offset (0000), pada bagian tengah adalah representasi isi memori pada masing-masing alamat dalam format hexadesimal, kemudian pada bagian kanan adalah representasi isi memori dalam format ASCII (sesuatu hal yang perlu diperhatikan adalah tidak semua karakter ASCII dapat diprint dilayar, untuk karakter ASCII yang tidak dapat di print dilayar ditampilkan sebagai titik (.).

Menampilkan isi register


Dalam pemrograman ASM, kita akan banyak berinteraksi dengan Register untuk berbagai proses pengolahan oleh CPU, misalnya penjumlahan, pengurangi, perkalian, pembagian, sampai kepada operasi logika dan bit.

Hendra, MT. & Hartono, M.Kom.

Pemrograman Bahasa Rakitan Untuk menampilkan isi Register dapat menggunakan perintah R (Register) -R AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=0B40 ES=0B40 SS=0B40 CS=0B40 IP=0100 NV UP EI PL NZ NA PO NC 0B40:0100 730B JNB 010D Pada gambar diatas dapat dijelaskan bahwa nilai register AX adalah 0000, nilai register BX adalah 0000, dan seterusnya. Kemudian register CS:IP menunjuk kelokasi 0B40:0010, dan isi memori lokasi yang ditunjuk adalah 730B (opcode bahasa mesin) yang direpresentasikan oleh JNB 010D (mnemonic bahasa assembly). Kemudian juga ditampilkan status dari register Flag sebagai berikut:
FLAG NAME------------SET----------------CLEAR Overflow-------------ov-----------------nv Direction------------dn-----------------up (increment) Interrupt------------ei (enabled)-------di (disabled) Sign-----------------ng (neg)-----------pl (positive) Zero-----------------zr-----------------nz Auxiliary carry------ac-----------------na Parity---------------pe (even)----------po (odd) Carry----------------cy-----------------nc

Trap flag (TF) tidak ditampilkan.

Mengubah nilai register


Pada beberapa perintah debug membutuhkan perubahan nilai register didalam operasinya, contohnya kita ingin menyimpan hasil pengetikan ke disk, maka perlu melakukan perubahan terhadap nilai register CX untuk menunjukan berapa byte data yang akan di tulis ke disk. Perubahan nilai register dilakukan dengan perintah R (register diikuti dengan nama register yang akan diganti), misalnya kita ingin menganti nilai Register AX menjadi 1234 hexa, maka perintah adalah RAX diikuti enter, dan kemudian mengetikan 1234 diikuti enter, setelah itu jika kita mengunakan perintah R untuk menampilkan isi register.
-R AX=0000 BX=0000 DS=0B40 ES=0B40 0B40:0100 730B -RAX AX 0000 :1234 CX=0000 DX=0000 SP=FFEE SS=0B40 CS=0B40 IP=0100 JNB 010D BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PO NC

Hendra, MT. & Hartono, M.Kom.

Pemrograman Bahasa Rakitan


-R AX=1234 BX=0000 DS=0B40 ES=0B40 0B40:0100 730B CX=0000 DX=0000 SP=FFEE SS=0B40 CS=0B40 IP=0100 JNB 010D BP=0000 SI=0000 DI=0000 NV UP EI PL NZ NA PO NC

Catatan: Untuk menganti isi dari register flag dapat dilakukan dengan mengetikan perintah RF (Register Flag), kemudian ketikan state dari flag yang mau diganti misalnya DN EI CY.

Program bahasa mesin anda yang pertama


Agar anda dapat lebih memahami perbedaan antara bahasa mesin dengan bahasa assembly, maka berikut ini kita akan membuat sebuah program yang menampilkan pesan hello world!. Bahasa mesin dalam bentuk representasi hexadesimal EB 10 68 65 6C 6C 6F 20 77 6F 72 6C 64 20 21 0D 0A 24 B4 09 BA 02 01 CD 21 B4 4C CD 21 Cara mengetikan bahasa mesin diatas : a. aktifkan program Debug b. ketik E 100 <enter> (E=Enter) c. ketik bilangan hexadecimal diatas diikuti dengan spasi, misalnya EB <spasi> 10 <spasi> 68 <spasi> dan seterusnya sampai selesai dan diakhiri dengan <enter> d. ketik RCX <enter>, kemudian ketik 1D. e. ketik N hello.com <enter> (N = Name) f. akhiri dengan perintah W (Write) g. ketikan U 100 (U=Unassembler) h. ketikan D 100 (D=Display) i. keluar dari program Debug dengan perintah Q (Quit). Contoh:
-E 100 0B40:0100 0B40:0108 0B40:0110 0B40:0118 73.eb 06.77 2E.0a 90.21 0B.10 96.6f 8B.24 2E.b4 43.68 90.72 0E.b4 8B.4c 43.65 04.6c 94.09 36.cd E2.6c 00.64 90.ba 34.21 F2.6c 5D.20 2E.02 2E.6f 5F.21 A1.01 C7.20 5B.0d 96.cd

Hendra, MT. & Hartono, M.Kom.

Pemrograman Bahasa Rakitan


-rcx CX 0000 :1d -n hello.com -w Writing 0001D bytes -u 100 0B40:0100 0B40:0102 0B40:0103 0B40:0104 0B40:0105 0B40:0106 0B40:0107 0B40:010A 0B40:010C 0B40:010D 0B40:010F 0B40:0112 0B40:0114 0B40:0117 0B40:0119 0B40:011B 0B40:011D 0B40:011F
-d 100 0B40:0100 0B40:0110 0B40:0120 0B40:0130 0B40:0140 0B40:0150 0B40:0160 0B40:0170 -q E:\920403024\ASM>hello.com hello world !

EB10 68 65 6C 6C 6F 20776F 726C 64 2021 0D0A24 B409 BA0201 CD21 B44C CD21 002F 0B169A90
EB 0A 16 00 00 FF 26 73 10 24 9A 75 75 E8 8A 08 68 B4 90 05 09 9E 4F E8 65 09 2E 2E 2E 00 08 0E 6C BA 8A FF C7 58 32 00

JMP DB DB DB DB DB AND JB DB AND OR MOV MOV INT MOV INT ADD OR


6C 02 1E 06 06 EB ED E2 6F 01 9C 94 96 03 0B F6

0112 68 65 6C 6C 6F [BX+6F],DH 0178 64 [BX+DI],AH AX,240A AH,09 DX,0102 21 AH,4C 21 [BX],CH DX,[909A]
20-77 CD-21 90-F8 90-2E 90-02 E8-1D C9-74 F9-EB 6F B4 C3 80 00 01 0D 06 72 4C 50 3C EB 58 8D 2E 6C CD 26 00 0E C3 6F 89 64 21 8B 75 50 F9 09 2E 20 00 07 19 B0 C3 E8 A9 21 2F A9 A9 03 55 19 90 0D 0B 02 01 B4 51 04 F8 ..hello world !. .$......!.L.!./. ..........P&.... .u........<.u... .u..........P... ....X.....X...UQ &.O.2...t..o.... s...............

Hendra, MT. & Hartono, M.Kom.

Pemrograman Bahasa Rakitan

Bab 2, Pemrograman 8086


Pemrograman 8086 merupakan dasar dari pemrograman untuk processor seri 80x86, dan seterusnya. Perintah Debug mensimulasikan lingkungan 8086 merupakan tools yang tersedia sejak DOS versi 2.0

Pengalamatan 8086
Pengalamatan memori pada 8086 adalah terbagi atas segment-segment. Suatu alamat direpresentasikan dalam dua bagian yaitu segment dan offset yang masing-masing merupakan alamat 16-bit unsigned. Karena Offset merupakan pengalamatan 16-bit, maka jangkauan masing-masing offset dalam segment adalah 64 Kb (64 x 1024). Contoh: FFFF:0005 dimana FFFF adalah segment, dan 0005 adalah offset. Secara fisik, pengalamatan 8086 menggunakan pengalamatan 20-bit, sehingga untuk mendapat alamat fisik, angka pada Segment digeser sebesar 8 bit ke kiri, dan kemudian dijumlahkan kembali ke offset, sehingga FFFF:0005 merepresentasikan alamat fisik FFFF5, yaitu FFFF0+0005 = FFFF5.

Data pada 8086


Pada pemrograman 8086 kita bekerja dengan data 16-bit yang disebut sebagai word atau dua byte (8-bit). Satu word disimpan didalam memori dengan urutan low byte terlebih dahulu dan diikuti dengan high byte, contoh misalnya kita ingin menyimpan $1234 (hexadesimal), maka pada memori akan tersimpan $34 diikuti dengan $12, hal ini sejalan untuk proses increment pada IP (instruction pointer) yang mengakses low byte terlebih dahulu.

Bilangan Signed dan Unsigned


CPU bekerja dengan data biner dan menggunakan bit tertentu sebagai tanda untuk bilangan, sebagai contoh data byte 8-bit dapat merepresentasikan 256 jenis objek yang berbeda. Pada bilangan unsigned (tidak bertanda) maka jangkauan nilai yang dapat dicapai adalah 0 s/d 255, sedangkan untuk bilangan yang sign (bertanda) kita dapat merepresentasikan nilai negatif -128 s/d -1, dan bilangan positif 0 s/d 127, sedangkan kalau dengan data word 16-bit dapat menjangkau -32,768 s/d 32,767, dan dengan data Hendra, MT. & Hartono, M.Kom. 7

Pemrograman Bahasa Rakitan double word (dword) 32-bit dapat menjangkau -2,147,483,648 s/d 2,147,483,647, sehingga secara umum n-bit dapat menjangkau nilai -2n-1 s/d 2n-1-1. Sekarang kita telah mengerti bagaimana jangkauan representasi data bertanda, tetapi bagaimana caranya kerjanya pada CPU 8086. CPU 8086 menggunakan notasi two's complement (komplemen dua). Pada sistem komplemen dua most significant bit (MSB) digunakan sebagai sign bit (bit tanda). Jika MSB adalah nol, bilangan tersebut adalah positif, dan jika MSB adalah satu, maka bilangan adalah negatif. Representasi bilanganbertanda untuk 8-bit adalah sebagai berikut.

Untuk mengkonversi suatu bilangan positif, menjadi bilangan negatif komplemen dua dilakukan dengan cara sebagai berikut: 1. Invers semua bit pada bilangan (aplikasikan operasi NOT) 2. Tambah satu pada hasil Invers (aplikasikan operasi INC) Contoh:
not 00000001 11111110 + 1 -----------11111111 (komplemen dua dari satu)

Konversi bilangan positif ke negatif dan sebaliknya pada 8086 dapat menggunakan perintah NEG.

Proses eksekusi
Processor mengambil perintah yang akan dieksekusi dari memori berdasarkan alamat yang ditunjuk oleh register CS (Code Segment) dan IP (Instruction Pointer). Pada sistim operasi DOS, suatu program COM akan ditempatkan mulai dari offset $100. Nilai dari register IP maupun CS akan berubah sesuai dengan perubahan titik eksekusi oleh Hendra, MT. & Hartono, M.Kom. 8

Pemrograman Bahasa Rakitan processor. Perubahan nilai CS:IP dapat dipengaruhi oleh perintah seperti JMP dan LOOP. Sesuatu yang perlu diperhatikan pada program COM adalah data dan kode terganbung pada segment yang sama, sehingga kita perlu menggunakan perintah JMP untuk melewati data, ataupun data ditempatkan dibawah kode.

Register 8086
Semua register pada 8086 adalah 16-bit, yang dapat dibagi menjadi low byte dan high byte. Ada empat register general purpose yaitu AX, BX, CX, dan DX, masing-masing register tersebut dibagi menjadi AL, AH, BL, BH, CL, CH, dan DL, DH. Register AX dikenal sebagai accumulator untuk hasil artimatika, register BX sering digunakan untuk menyimpan alamat base, register CX sering digunakan untuk counter pada proses perulangan, sedangkan register DX sering untuk pengalamatan I/O dan data. Selain register general-purpose, terdapat juga index register yaitu SI (source index) dan DI (destination index) yang umumnya digunakan untuk pengalamatan dan operasi string. Kemudian terdapat register untuk pengelolaan data terkait dengan stack yaitu SP (Stack Pointer, BP (Base Pointer) dan SS (Stack Segment).

Untuk pengelolaan data dapat menggunakan DS (Data Segment) dan ES (Extra Segment). Selain register tersebut diatas, pada 8086 terdapat sebuah register special yaitu register Flag yang menunjukan status yang dihasilkan dari hasil eksekusi dari suatu instruksi atau operasi kendali lainnya. Hendra, MT. & Hartono, M.Kom. 9

Pemrograman Bahasa Rakitan Ada enam flag sebagai flag status yaitu AF, CF, OF, SF, PF dan ZF, dan tiga sisanya adalah flag kendali yaitu DF, IF dan TF. Penjelasan dari masing-masing flag adalah sebagai berikut: AF (auxiliary flag), flag ini di set ketika terjadi carry out atau borrow pada 4 bit LSB. Flag ini digunakan pada saat instruksi logika dan aritmetika. CF (carry flag), flag ini diset ketika terjadi carry out atau overflow pada MSB. Ini digunakan oleh instruksi yang melakukan penjumlahan (ADC) dan pengurangan (SBB) angka banyak byte. OF (overflow flag), flag ini diset ketika suatu overflow aritmatika terjadi, dimana terjadi kehilangan pada digit MSB karena ukuran dari hasil melebihi kapasitas dari lokasi tujuan penampungan. SF (sign flag), karena bilangan binari negatif direpresentasikan pada 8086 dalam bentuk notasi komplemen dua. SF mengindikasikan sign dari hasil (0 = positif, 1 = negatif). PF (parity flag), flag ini diset ketika hasil adalah parity even, flag ini dapat digunakan untuk mengecek kesalahan transmisi. ZF (zero flag), flag ini diset ketika hasil operasi adalah 0, digunakan untuk sebagai hasil aritmatika dan perbadingan data. DF (direction flag). Jika DF diset menyebabkan instruksi string melakukan autodecrement (hitungan mundur), dalam hal ini proses dari string dari alamat yang besar ke alamat yang kecil, atau dari kanan ke kiri. Jika nilai DF diclear menyebabkan instruksi string ke auto-increment (count up), atau proses string dari kiri ke kanan. IF (interrupt-enable flag), jika nilai IF di set, artinya memperbolehkan MPU untuk menangani eksternal maskable interrupt request. Jika nilai IF di clear artinya MPU mengabaikan interrupt jenis tersebut. IF tidak ada efek terhadap nonmaskable interrupt (NMI) dan internal generated interrupt. TF (trap flag), setting TF menempatkan processor pada modus single-step untuk debugging. Pada modus ini MPU secara otomatis membuat suatu internal interrupt setelah setiap instruksi.

Stack
Suatu stack adalah suatu bagian dari memori yang disisihkan untuk menyimpan alamat dan data ketika suatu subrutin dijalankan maupun terjadinya interrupt. Pada MPU 8086, suatu 64 Kb segment dicadangkan sebagai stack. 16 bit alamat awal segment disimpan pada register Stack Segment (SS), dan register Stack Pointer (SP) mengandung 16-bit offset dimulai dari awal segment ke lokasi memori dimana suatu word yang paling akhir disimpan ke Stack.

Hendra, MT. & Hartono, M.Kom.

10

Pemrograman Bahasa Rakitan

Gambar tersebut diatas dapat dijelaskan bahwa SS=$5000, dan SP=$FFE0, alamat fisik dari Top of the stack saat ini adalah $5FFE0.

Instruksi 8086
Suatu instruksi pada 8086 dapat terdiri dari satu sampai enam byte, ditambah dengan byte opsional pengendali segment.
machine code : xxxxxxdw|[mdregr/m]|[xxxxxxxx[xxxxxxxx]]|[xxxxxxxx[xxxxxxxx]] opcode |mdr/m byte| disp 1 / 2 bytes |imm. data 1 / 2 bytes

Contoh:
JMP unconditional jump direct within segment direct within segment-short indirect within segment direct intersegment indirect intersegment move data register/mem. to/from register immediate to reg./mem. immediate to register mem. to accu (AX/AL) accu to mem. (AX/AL) reg./mem. to segm. reg. segm. reg. to reg./mem. interrupt type specified 11101001 11101011 11111111 11101010 11111111 disp16bit disp8bit md100r/m offset:seg32bit md101r/m

MOV

100010dw 1100011w 1011wreg 1010000w 1010001w 10001110 10001100

mdregr/m md000r/m data8/16bit data8/16bit address16bit address16bit md0srr/m md0srr/m

INT

11001101

type8bit

Hendra, MT. & Hartono, M.Kom.

11

Pemrograman Bahasa Rakitan


type 3 11001100

Untuk jelasnya dapat dilihat pada Lampiran Opcode 8086.

Opcode Byte
Setiap byte pertama dari instruksi adalah byte opcode, yang menspesifikasikan operasi yang akan dilakukan. Jika ada data yang harus ditangani, maka byte kedua adalah byte pengalamatan, jika ada pemindahan (displacement) atau data lain diperlukan, maka akan ditambahkan pada byte berikutnya. Opcode dari suatu instruksi transfer data, dapat dibagi menjadi tiga bagian opcode, bit d, dan bit w. bit d menspesifikasikan bit direction, bit w adalah menspesifikan ukuran w =0 adalah operasi 8 bit, dan w = 1 adalah operasi 16 bit. Opcode untuk instruksi yang tidak memanipulasi data tidak memiliki bit d atau w. Sebagai contoh, instruksi untuk duplikasi data dari memori ke register, dari register ke memori, atau dari register ke register memiliki opcode 1000 10dw

Byte Pengalamatan
Byte kedua memspesifikasikan modus pengalamatan, byte ini dalam bentuk mdregr/m. Bit md memspesifikasikan interpretasi dari bit r/m, dan memberikan jumlah dari byte pemindahan yang harus dilakukan, dan bit reg mespesifikasikan register. r/m 000 001 010 011 100 101 110 111 mem BX+SI BX+DI BP+SI BP+DI SI DI ABS BX w=0 AL CL DL BL AH CH DH BH w=1 AX CX DX BX SP BP SI DI

Jenis register yang dispesifikasikan tergantung kepada bit w. Berdasarkan tabel diatas untuk nilai r/m=000 dapat menspesifikasikan register AL untuk w=0, dan register AX untuk w=1. Jika bit d=0, maka source adalah reg dan destination adalah r/m, dan jika d =1, maka source adalah r/m dan destination adalah reg.

Hendra, MT. & Hartono, M.Kom.

12

Pemrograman Bahasa Rakitan Jika bit md=11, maka bit r/m juga mengacu kepada suatu register, dengan menggunakan kode yang sama untuk reg. Jika bit md=00, maka referensi memori adalah pada kolom kedua dari tabel, dan tidak ada byte perpindahan, kecuali untuk kasus r/m = 110 (absolute), ketika suatu offset 16-bit dispesifikasikan pada dua byte berikutnya. Secara default hal ini relatif terhadap register segment DS. Jika bit md=01, maka merupakan offset 8 bit. Jika bit md=10, maka merupakan offset 16 bit. Contoh:
EB 68 B4 BA CD B4 CD JMP 10 65 6C 6C 6F 20 77 6F 72 6C 64 20 21 0D 0A 24 09 02 01 21 4C 21 unconditional jump direct within segment direct within segment-short indirect within segment direct intersegment indirect intersegment

11101001 11101011 11111111 11101010 11111111

disp16bit disp8bit md100r/m offset:seg32bit md101r/m

EB 10 EB = 11101011 = JMP jadi EB 10 adalah JMP 10 dalam hal ini adalah melakukan jump sebanyak 16 byte kedepan. 68 65 6C 6C 6F 20 77 6F 72 6C 64 20 21 0d 0A 24 dalam hal ini adalah Hello World !, 0d,0a, $ yaitu pesan Hello World ! diikuti dengan CR, dan LF, dan $ yang merupakan end of string yang secara total adalah 16 byte atau $10. B4 09
MOV move data register/mem. to/from register immediate to reg./mem. 100010dw 1100011w mdregr/m md000r/m

data8/16bit

Hendra, MT. & Hartono, M.Kom.

13

Pemrograman Bahasa Rakitan


immediate to register mem. to accu (AX/AL) accu to mem. (AX/AL) reg./mem. to segm. reg. segm. reg. to reg./mem. 1011wreg 1010000w 1010001w 10001110 10001100 data8/16bit address16bit address16bit md0srr/m md0srr/m

B4 = 10110100 dimana w = 0, dan reg = 100, untuk reg = 100 dan w = 0 adalah AL jadi perintah B4 09 adalah MOV AH, 9 BA 02 01 BA = 10111010 dimana w = 1, dan reg = 010, untuk reg = 010 dan w = 1 adalah DX 02 01 adalah word $102 dengan low byte adalah 02 dan high byte adalah 01 jadi perintah BA 02 01 adalah MOV DX, 102 CD 21
INT interrupt type specified type 3 11001101 11001100 type8bit

CD = 11001101 Jadi CD 21 adalah INT 21 B4 4C adalah MOV AH, 4C CD 21 adalah INT 21 Latihan 1. Buatlah program bahasa mesin untuk program assembly berikut ini : JMP Selamat Belajar Assembly, CR, LF, $ MOV AH, 9 MOV DX, 102 INT 21

Hendra, MT. & Hartono, M.Kom.

14

Pemrograman Bahasa Rakitan MOV AH, 4C INT 21 2. Buatlah program bahasa mesin yang dapat menampikan nama dan nim anda dengan dua kali cetak. 3. Ujilah program bahasa mesin anda dengan menggunakan program debug.

Hendra, MT. & Hartono, M.Kom.

15

Pemrograman Bahasa Rakitan

Bab 3, Bahasa rakitan x86


Pada bagian sebelumnya kita telah membahas tentang pemrograman 8086 dengan menggunakan bahasa mesin, dan pada bagian ini kita akan membahas tentang pemrograman x86 Assembly.

Mnemonic dan Opcode


Setiap perintah assembly x86 direpresentasikan dengan suatu mnemonic yang mana merupakan kombinasi dari satu atau lebih operand, dan diterjemahkan menjadi satu atau lebih byte yang disebut sebagai opcode, misalnya perintah INT 21 diterjemahkan menjadi CD 21.

Assembler
Setiap program yang ditulis dengan menggunakan perintah assembly tidak dapat secara langsung dieksekusi oleh mesin, tetapi membutuhkan proses Assembly menggunakan software Assembler. Software Assembler yang paling sederhana adalah dengan menggunakan Debug.exe, dan untuk program yang lebih besar dan kompleks, tentu saja pemakaian Debug.exe tidak memadai, sehingga anda dapat menggunakan program assember seperti TASM, MASM, dan NASM.

Assembler pada Debug


Untuk pembuatan program assembly dengan Debug dapat dilakukan dengan menggunakan perintah A (Assembly), adapun keterbatasan pada program Debug adalah hanya dapat membuat program COM, dan setiap program COM harus ditempatkan mulai dari lokasi memori $100. Contoh: -a 100 0B40:0100 jmp 112 0B40:0102 db 'Hello World !',0d,0a,'$' 0B40:0112 mov ah,9 0B40:0114 mov dx,102 0B40:0117 int 21 0B40:0119 mov ah,4c 0B40:011B int 21 0B40:011D -n helloasm.com -h 11D 100 021D 001D -rcx Hendra, MT. & Hartono, M.Kom. 16

Pemrograman Bahasa Rakitan CX 0000 :1d -w Writing 0001D bytes Proses diatas dapat dijelaskan bahwa pada awalnya kita memberikan perintah A (Assembler), dimana hasil assembler ditempatkan pada lokasi memori $100, kemudian kita mengetikan perintah-perintah dalam bahasa assembly (mnemonic), kemudian dilanjutkan dengan menyimpan hasil assembler ke suatu file helloasm.com, dan melakukan penulisan sebanyak $1d byte dengan merubah nilai register CX, dan diakhiri dengan perintah w. Nilai $1d diperoleh dengan mengurangkan $11d dengan $100, proses Hexa arithmetic (fasilitas kalkulator pada DEBUG) dapat menggunakan perintah h11D 100, dan akan ditampilkan hasil penjumlahan ($21d) dan hasil pengurangan ($1d). -h 11D 100 021D 001D

UnAssembler pada Debug


Program hasil assembler dapat di UnAssember dengan memberikan perintah U (UnAssembler) yang diikuti dengan lokasi memori bahasa mesin yang akan di UnAssembler. Contoh:
D:\920403024\ASM>debug helloasm.com -u 100 0BB0:0100 EB10 JMP 0112 0BB0:0102 48 DEC AX 0BB0:0103 65 DB 65 0BB0:0104 6C DB 6C 0BB0:0105 6C DB 6C 0BB0:0106 6F DB 6F 0BB0:0107 20576F AND [BX+6F],DL 0BB0:010A 726C JB 0178 0BB0:010C 64 DB 64 0BB0:010D 2021 AND [BX+DI],AH 0BB0:010F 0D0A24 OR AX,240A 0BB0:0112 B409 MOV AH,09 0BB0:0114 BA1201 MOV DX,0102 0BB0:0117 CD21 INT 21 0BB0:0119 B44C MOV AH,4C 0BB0:011B CD21 INT 21

;Hello World

;CR, LF, '$'

;exit to DOS

Pada sisi kolom pertama adalah alamat memori yang masing instruksi mesin, pada kolom Hendra, MT. & Hartono, M.Kom. 17

Pemrograman Bahasa Rakitan kedua adalah opcode dari masing-masing perintah, pada kolom terakhir adalah bahasa assembly.

Latihan
1. Buatlah program dalam bahasa assembly yang dapat mencetak Belajar Bahasa Assembly !. 2. Buatlah program assembly berikut ini : -a 100 0BB0:0100 jmp 127 0BB0:0102 db 'Selamat belajar program assembly !',0d,0a,'$' 0BB0:0127 mov cx,5 0BB0:012A mov ah,9 0BB0:012C mov dx,102 0BB0:012F int 21 0BB0:0131 loop 12a 0BB0:0133 mov ah,4c 0BB0:0135 int 21 0BB0:0137 mov ah,4c 0BB0:0139 3. Modifikasi program tersebut diatas untuk mencetak pesan selamat belajar program assembly menjadi 20 baris. 4. Cobalah program Caps_On berikut ini :
mov ax,0040 mov ds,ax or byte ptr [0017],40 mov ah,1 int 16 mov ax,4c00 int 21

5. Cobalah program Caps_Off berikut ini :


mov mov and mov ax,0040 ds,ax byte ptr [0017],bf ah,1

int 16 mov ax,4c00 int 21

Hendra, MT. & Hartono, M.Kom.

18

Pemrograman Bahasa Rakitan

Bab 4, Interrupt dan Pemakaiannya


Kadang-kadang proses dalam CPU mengalami interrupsi untuk kejadian-kejadian yang perlu segera mendapat respon, seperti pengetikan pada keyboard, proses I/O lainnya, dan clock tick untuk mengupdate waktu system. Pada prinsipnya interrupt terbagi atas eksternal, dan internal. Eksternal interrupt dibangkitkan oleh proses diluar program seperti proses I/O, dan clock, sedangkan proses Internal interrupt dibangkitkan oleh proses program seperti devide for zero error (Traps interrupt) dan Software interrupt (dibangkitkan dengan perintah INT). Ketika suatu interrupt terjadi, processor akan menyelesaikan siklus memori saat ini, dan bercabang kepada rutin khusus menanggani interrupt tersebut, status dari program saat ini akan disimpan dan rutin interrupt handle umumnya akan mengembalikan kendali ke program termasuk semua nilai register seakan-akan tidak pernah terjadi sesuatu (hanya kehilangan beberapa siklus CPU), sedangkan Traps interrupt tidak akan kembali ke program dan menghentikan program tersebut. Catatan : Pada bagian ini kita akan lebih memfokuskan diri pada Software interrupt

Maskable Interrupt
Processor dapat mencegah interrupt dengan menggunakan mask bit khusus interrupt. Mask bit ini adalah bagian dari flag register pada microprocessor 8086 yang dikenal sebagai interrupt flag (IF), jika bit ini clear (IF=0), dan terjadi permintaan interrupt pada pin Interrupt Request, maka permintaan tersebut akan diabaikan.

Non-Maskable Interrupt (NMI)


Ada beberapa interrupt yang mana tidak dapat di mask atau diabaikan oleh processor, hal ini terkait dengan tugas-tugas prioritas tinggi yang tidak boleh diabaikan (seperti terjadi pariti pada memori atau kegagalan BUS). NMI memiliki prioritas yang absolut, dan ketika itu terjadi, processor menyelesaikan siklus memori saat ini, dan kemudian bercabang ke rutin khusus yang ditulis untuk menangani permintaan interrupt.

Interrupt pada 8086


Adapun urutan dari proses interrupt pada microprocessor 8086 dapat dijelaskan sebagai berikut: 1. Interface eksternal mengirim suatu sinyal interrupt ke pin Interrupt Request (INTR), atau suatu internal interrupt terjadi. 2. CPU menyelesaikan instruksi yang berlangsung dan mengirim (untuk suatu hardware interrupt) dan mengirim Interrupt Acknowledge (INTA) ke interface hardware. Hendra, MT. & Hartono, M.Kom. 19

Pemrograman Bahasa Rakitan 3. Interrupt jenis N (masing-masing interrupt memiliki nomor) dikirim ke Central Processing Unit (CPU) melalui data bus dari interface hardware. 4. Isi dari register flag didorong ke stack. 5. Flag interrupt (IF) dan trap (TF) di clear, hal ini akan mencegah pin INTR dan kemampuan single-step untuk proses debugging (trap) 6. Isi dari register CS didorong ke Stack 7. Isi dari register IP didorong ke Stack 8. Isi dari vektor interrupt diambil, dari (4 x N) dan kemudian ditempatkan ke IP dan dari (4 x N + 2) ke CS, sehingga instruksi berikutnya yang akan dijalankan adalah procedure dari interrupt service berdasarkan alamat pada interrupt vector. 9. Ketika kembali dari rutin interrupt-service oleh instruksi Interrupt Return (IRET), nilai IP, CS dan register Flag akan ditarik dari Stack dan kembali ke kondisi sebelum terjadinya interrupt.

Software Interrupt
Software interrupt merupakan fungsi-fungsi yang disediakan oleh BIOS maupun sistim operasi, dimana fungsi-fungsi tersebut membuat tugas pemrograman menjadi lebih mudah, dari pada menulisnya sendiri dari awal, anda cukup mengirimkan nilai input yang dibutuhkan melalui register, kemudian memanggil rutin interrupt tersebut, dan selanjutnya rutin interrupt akan melakukan fungsinya dan mengembalikan nilai hasil proses melalui register. Fungsi yang tersedia dalam interrupt dapat terdiri dari layanan hardware seperti screen, diskdrive, printer, serial port dan keyboard, maupun layanan secara software seperti directory dan file. Untuk melakukan panggilan terhadap rutin interrupt menggunakan perintah INT N Dimana N merupakan nomor interrupt yang dapat bernilai 0 s/d 255, yang umumnya ditulis secara hexadecimal 0 s/d FF Pada kenyataannya masing-masing interrupt terbagi lagi sub-sub layanan, yang ditentukan pada nilai register AH, sebelum interrupt tersebut dipanggil, sehingga kita dapat memiliki 256 x 256 = 65536 fungsi layanan.

Hendra, MT. & Hartono, M.Kom.

20

Pemrograman Bahasa Rakitan

Pemakaian Interrupt
Seperti yang telah dijelaskan sebelumnya, salah satu parameter layanan fungsi interrupt adalah sub layanan yang ditentukan oleh nilai register AH, selain nilai register AH, kita juga perlu mengisi nilai-nilai register lainnya sesuai dengan kebutuhan layanan interrupt tersebut. Contoh: INT 21,9 - Print String AH = 09 DS:DX = menunjuk alat suatu striung yang diakhir dengan "$" returns nothing - outputs character string to STDOUT up to "$" - backspace is treated as non-destructive - if Ctrl-Break is detected, INT 23 is executed Berdasarkan data tersebut diatas, maka untuk pemakaian interrupt $21, sub layanan $9 dengan fungsi Print String, maka perlu ditentukan nilai register AH=$9, dan kemudian nilai register DS:DX menunjuk ke alamat suatu string yang diakhiri dengan '$'. Coba kita review kembali program hello world sebelumnya. Dimana kita menggunakan INT $21 sub layanan AH=$9 untuk mencetak tulisan yang berada dioffset DX=$102. Jadi dalam hal ini AH dan DX merupakan parameter bagi INT $21.
0B11:0100 0B11:0102 0B11:0112 0B11:0114 0B11:0117 0B11:0119 0B11:011B jmp 112 db 'hello world !',0d,0a,'$' mov ah,9 mov dx,102 int 21 mov ah,4c int 21

Dalam hal ini kita tidak menentukan nilai DS, karena secara default pada program jenis COM, nilai DS, ES, dan SS adalah sama dengan CS. Pada contoh sebelumnya kita bekerja dengan rutin interrupt yang tidak mengembalikan hasil, tetapi hanya proses mencetak string ke layar, berikut ini kita akan membahas rutin interrupt yang mengembalikan hasil. INT 21,8 - Console Input Without Echo AH = 08 Hendra, MT. & Hartono, M.Kom. 21

Pemrograman Bahasa Rakitan

on return: AL = character from STDIN - returns 0 for extended keystroke, then function must be called again to return scan code - waits for character from STDIN and returns data in AL - if Ctrl-Break is detected, INT 23 is executed Berdasarkan data tersebut diatas, maka untuk menjalankan fungsi Int $21 Console Input Without Echo, kita perlu ditentukan nilai register AH=$8, dan interrupt rutin akan menunggu karakter dari STDIN, jika ada karakter yang diketik, maka akan disimpan di register AL. Untuk kongkritnya mari kita lihat contoh berikut ini, dimana setelah mencetak pesan Ketik huruf A untuk selesai, program akan menanti input dari keyboard dengan menggunakan INT $21 sub layanan AH=$8, dan nilai ASCII dari input keyboard akan dikembalikan di register AL. Selanjutnya program dapat membandingkan nilai register AL dengan $41 (65 desimal).
0B11:0100 0B11:0102 0B11:0105 0B11:0107 0B11:0109 0B11:010B 0B11:010D 0B11:010F 0B11:0111 0B11:0113 0B11:0131 mov ah,9 mov dx,113 int 21 mov ah,8 ;baca dari STDIN tanpa echo int 21 ;karakter dikembalikan ke AL cmp al,41 jnz 100 mov ah,4c int 21 db Ketik huruf A untuk selesai,0d,0a,$

Latihan
1. Misalkan diberikan suatu data interrupt sebagai berikut: INT 21,39 - Create Subdirectory (mkdir) AH = $39 DS:DX = pointer to ASCIIZ path name on return: CF = 0 if successful = 1 if error AX = error code (see DOS ERROR CODES) Hendra, MT. & Hartono, M.Kom. 22

Pemrograman Bahasa Rakitan - creates specified subdirectory - returns error if directory already exists, element of the path is not found, directory full or write protected disk Catatan: ASCIIZ adalah suatu string yang diakhiri dengan null (0) Buatlah sebuah program assembly yang dapat membuat directory di E:\Hendra. 2. Misalkan diberikan suatu data interrupt sebagai berikut: INT 21,3B - Change Current Directory (chdir) AH = $3B DS:DX = pointer to ASCIIZ path name on return: CF = 0 if successful = 1 if error AX = error code if CF set (see DOS ERROR CODES) - changes the current directory to the directory specified by pointer DS:DX Buat program yang dapat mengaktifkan ke directory E:\Hendra. 3. Misalkan diberikan suatu data interrupt sebagai berikut: INT 21,56 - Rename File AH = $56 DS:DX = pointer to old ASCIIZ path/filename ES:DI = pointer to new ASCIIZ path/filename on return: AX = error code if CF set (see DOS ERROR CODES) - supports full pathnames and allows renaming files across directories and in DOS 3.x allows renaming subdirectories - does not support use of wildcards unless invoked from via INT $21, $5D in which case error code $12 is returned - unpredictable result may occur if an opened file is renamed - see Bibliography reference to "Undocumented DOS" Buatlah program yang dapat mengubah directori E:\Hendra menjadi E:\Susan

Hendra, MT. & Hartono, M.Kom.

23

Pemrograman Bahasa Rakitan

Quiz :
1. Jika anda diberi data sebagai berikut INT 10h / AH = 2 setting posisi cursor. input: DH = baris. DL = kolom. BH = nomor halaman (0..7). Contoh: mov dh, 10 mov dl, 20 mov bh, 0 mov ah, 2 int 10h Buatlah program yang dapat mencetak tulisan Hello World pada lokasi 10,10. 2. Jika anda diberi data sebagai berikut INT 10h / AH = 03h mendapatkan posisi cursor dan ukuran. input: BH = page number. return: DH = row. DL = column. CH = cursor start line. CL = cursor bottom line. Untuk menyimpan nilai register 16-bit ke Stack anda dapat mengunakan perintah PUSH, dan untuk mengambil kembali nilai dari Stack anda dapat menggunakan POP. Contoh: Push DX Pop DX Buatlah program yang dapat mencetak tulisan Hello World pada lokasi 10,10 dan mengembalikan posisi cursor ke lokasi semula sebelum proses pencetakan.

Hendra, MT. & Hartono, M.Kom.

24

Pemrograman Bahasa Rakitan 3. Jika anda diberi data sebagai berikut INT 10h / AH = 06h menggulung layar ke atas. INT 10h / AH = 07h menggulung layer ke bawah. input: AL = jumlah baris yang digulung (00h = membersihkan layar). BH = attribute untuk baris kosong pada bagian bawah window. CH, CL = row, column sisi kiri atas jendela. DH, DL = row, column sisi kanan bawah jendela. Atribut
HEX 0 1 2 3 4 5 6 7 8 9 A B C D E F BIN 0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111 COLOR black blue green cyan red magenta brown light gray dark gray light blue light green light cyan light red light magenta yellow white

Jika nilai BH = $07, berarti warna background adalah black (0), dan warna foreground adalah light gray (7). Jumlah Baris = 0 s/d 24 Jumlah Kolom = 0 s/d 79 Buatlah program yang mensimulasi perintah CLS pada DOS, dan mengeser kursor ke posisi sudut kiri atas. 4. Jika anda diberi data berikut : INT 16h / AH = 00h - ambil keystroke dari keyboard (no echo). return: AH = BIOS scan code. Hendra, MT. & Hartono, M.Kom. 25

Pemrograman Bahasa Rakitan AL = ASCII character. (if a keystroke is present, it is removed from the keyboard buffer). INT 10h / AH = 0Eh - teletype output. input: AL = karakter yang dicetak. Fungsi ini menampilkan suatu karakter pada layer, memajukan cursor dan mengulung layer bila perlu, pencetakan dilakukan pada halaman yang aktif. Contoh: mov al, 'a' mov ah, 0eh int 10h Buatlah program yang mengambil satu ketukan dari keyboard dan mencetak kelayar pada posisi cursor aktif.

Hendra, MT. & Hartono, M.Kom.

26

Pemrograman Bahasa Rakitan

Bab 5, Memori dan pengalamatan


Arsitektur x86 mengimplementasikan memori tersegmentasi, dimana memori dibagi menjadi bagian-bagian yang dapat dialamatkan oleh sebuah register index tunggal (16bit) tanpa mengubah bagian selektor 16-bit. Masing-masing segment selalu berukuran 64 Kb (menggunakan offset 16-bit). Pengalamatan fisik memori pada 8086 menggunakan pengalamatan 20-bit (5 digit Hexa) yang dalam penulisannya dibagi atas segment dan offset, misalnya sebuah alamat 0040:0010 secara fisik adalah 00410.

Modus pengalamatan Register


Kebanyakan instruksi pada 8086 beroperasi pada register general purpose dengan menspesifikasikan nama dari register sebagai operand pada instruksi, anda dapat mengakses kepada isi dari register tersebut dengan perintah MOV dest, source. Instruksi ini menduplikasi data dari operand source ke operand target. Sesuatu hal yang perlu diperhatikan adalah kedua operand harus berukuran yang sama. Contoh:
mov mov mov mov mov mov ax, dl, si, sp, dh, ax, bx al dx bp cl ax ;Copies the value from ;Copies the value from ;Copies the value from ;Copies the value from ;Copies the value from ;Yes, this is legal! BX AL DX BP CL into into into into into AX DL SI SP DH

Sesuatu hal yang perlu diingat adalah register merupakan tempat yang terbaik untuk menyimpan variabel yang sering digunakan, instruksi yang menggunakan register adalah lebih pendek dan cepat dibandingkan dengan akses memori. Anda tidak dapat melakukan operasi mov terhadap suatu register segment ke register segment lainnya, untuk melakukan hal ini anda dapat menggunakan instruksi sebagai berikut :
mov mov atau push pop ax ds ax, cs ds, ax

Modus pengalamatan Memori


CPU 8086 menyediakan berbagai cara yang berbeda untuk mengakses memori, modus Hendra, MT. & Hartono, M.Kom. 27

Pemrograman Bahasa Rakitan pengalamatan yang disediakan adalah displacement, base, displacement+base, base+indexed, dan displacement+base+indexed. Secara default jika tidak dituliskan, maka register segment yang digunakan untuk data adalah DS, dan untuk stack adalah SS.

Displacement
Merupakan modus pengalamatan yang paling umum, dan yang paling mudah dipahami, displacement terdiri dari konstanta 16-bit yang menspesifikasikan alamat offset dari memori target. Instruksi MOV AL,[8088] adalah mengisi register AL dengan isi memori yang secara fisik ditunjuk oleh DS:8088, dan sebaliknya MOV [1234],DL adalah mengisi lokasi memori DS:1234 dengan nilai register DL.

Pada contoh diatas, kita bekerja dengan register satu byte, bagaimana kalau kita menulis MOV AX,[1234], dimana AX adalah register word. Perintah ini akan menduplikasi nilai byte dari lokasi memori DS:1234 ke register AL, dan DS:1235 ke register AH.

Pemakaian modus displacement cocok jika kita mengacu pada variable tunggal, tetapi jika kita melakukan pengolahan Array maupun String tentu saja metode ini kurang sesuai. Secara default modus displacement bekerja pada data-segment, jika anda bermaksud mengacu pada alamat memori berdasarkan register segment lainnya, maka anda perlu menuliskan MOV AX, ES:[0017] yang artinya mengisi register AX dengan nilai word dari lokasi memori ES:0017. Jika source adalah immediately, secara default adalah dianggap sebagai WORD, jika anda immediately tersebut dimaksud adalah byte, maka anda perlu menambahkan kata byte contoh : mov [1234], 10 'akan mengisi byte 10 ke memori DS:1234 28

Hendra, MT. & Hartono, M.Kom.

Pemrograman Bahasa Rakitan 'dan byte 00 ke memori DS:1235 mov byte [1234],10 'akan mengisi byte 10 ke memori DS:1234

Modus Pengalamatan Register Indirect


CPU 8086 memperbolehkan anda mengakses memori secara indirect dengan menggunakan modus pengalamatan indirect. Adapun register yang dapat digunakan untuk mengakses memori secara indirect adalah bx, bp, si dan di. Sebagaimana pada penulisan berikut:
mov mov mov mov al, al, al, al, [bx] [bp] [si] [di]

Penulisan tersebut diatas akan menduplikasi nilai byte yang ditunjuk oleh ds:[bx], ss:[bp], ds:[si], dan ds[di] ke register al.

Sesuatu hal yang perlu anda perhatikan adalah bahwa khusus untuk register BP secara default menggunakan SS. Jika anda ingin mengacu pada register segment lainnya, maka anda dapat menambahkan segment register pada penulisan.
mov mov mov mov al, al, al, al, cs:[bx] ds:[bp] ss:[si] es:[di]

Hendra, MT. & Hartono, M.Kom.

29

Pemrograman Bahasa Rakitan

Modus pengalamatan Indexed


Modus pengalamatan indexed menggunakan sintak penulisan sebagai berikut:
mov mov mov mov al, al, al, al, [bx+disp] [bp+disp] [si+disp] [di+disp] mov mov mov mov al, al, al, al, ss:[bx+disp] es:[bp+disp] cs:[si+disp] ss:[di+disp]

Displacement merupakan suatu konstanta 8-bit ataupun 16-bit Jika bx berisi nilai $1000 dan konstanta disp adalah $234, maka MOV AL,[bx+234] adalah mengisi nilai byte dari lokasi DS:1234 ke register AL.

Modus Pengalamatan Base Index


Pengalamatan modus base index secara sederhana mengkombinasikan register base (bx atau bp) dengan register index (si atau di), adapun bentuk penulisan yang ada yaitu:
mov mov mov mov al, al, al, al, [bx+si] [bx+di] [bp+si] [bp+di]

Secara default untuk register bx mengacu kepada DS, dan register bp mengacu kepada SS.

Hendra, MT. & Hartono, M.Kom.

30

Pemrograman Bahasa Rakitan

Modus pengalamatan Base+Index+Displacement


Modus pengalamatan ini mengkombinasikan register base (bx atau bp) dengan register index (si atau di) dan ditambah dengan sebuah konstanta disp 8-bit atau 16-bit, adapun bentuk penulisan yang ada adalah:
mov mov mov mov al, al, al, al, [bx+si+disp] [bx+di+disp] [bp+si+disp] [bp+di+disp]

Berdasarkan kombinasi dari berbagai modus pengalamatan tersebut diatas, maka pada CPU 8086 terdapat 17 bentuk pengalamantan yaitu : disp, [bx], [bp], [si], [di], disp[bx],
disp[bp], disp[si], disp[di], [bx][si], [bx][di], [bp][si], [bp][di], disp[bx][si], disp [bx][di], disp[bp][si], and disp[bp][di].

Untuk memudahkan anda mengingat berbagai macam pengalamatan tersebut diatas, maka anda dapat mengingat gambar berikut:

Hendra, MT. & Hartono, M.Kom.

31

Pemrograman Bahasa Rakitan

Pertukaran nilai
Perintah XCHG dapat digunakan untuk pertukaran data antara register dengan register, register dengan memori, memori dengan register. Contoh:
Mov AX, 5 Mov [10], 7 XCHG AX,[10]

Mengambil nilai dari Tabel


Perintah XLATB dapat digunakan untuk menduplikasi nilai byte dari DS:[BX+AL] ke register AL. Contoh: -a 100 0B40:0100 jmp 112 0B40:0102 db '0123456789ABCDEF' 0B40:0112 mov bx,102 0B40:0115 mov al,0a 0B40:0117 xlat 0B40:0118 Maka nilai al adalah 9

Latihan
1. Misalkan anda diberi data sebagai berikut: Pada lokasi memori FFFF:0005 s/d FFFF:000C berisi BIOS Revision Date
-d FFFF:0005 FFFF:0000 30 36 2F-31 32 2F 30 38 00 FC 00 FFFF:0010 34 12 00 00 00 00 00 00-00 00 00 00 00 00 00 00 06/12/08... 4...............

Dan perintah untuk mencetak karakter ke STDOUT adalah sebagai berikut INT 21,2 - Display Output AH = 02 DL = character to output returns nothing

Hendra, MT. & Hartono, M.Kom.

32

Pemrograman Bahasa Rakitan - outputs character to STDOUT - backspace is treated as non-destructive cursor left - if Ctrl-Break is detected, INT 23 is executed Buatlah program yang dapat mencetak BIOS Revision Date is 06/12/08. 2. Misalkan anda diberi data sebagai berikut: INT 21,1 - Keyboard Input with Echo AH = 01 on return: AL = character from standard input device - waits for keyboard input from STDIN and echoes to STDOUT - returns 0 for extended keystroke, then function must be called again to return scan code - if Ctrl-Break is detected, INT 23 is executed Buatlah program yang dapat menerima 3 karakter, dan mencetak kembali Anda mengetik huruf : XXX 3. Misalkan anda diberi data sebagai berikut: INT 21,39 - Create Subdirectory (mkdir) AH = 39h DS:DX = pointer to ASCIIZ path name on return: CF = 0 if successful = 1 if error AX = error code (see DOS ERROR CODES) - creates specified subdirectory - returns error if directory already exists, element of the path is not found, directory full or write protected disk Catatan: ASCIIZ adalah suatu string yang diakhiri dengan null (0) Hendra, MT. & Hartono, M.Kom. 33

Pemrograman Bahasa Rakitan

Untuk program jenis COM, program line parameter dapat diperoleh pada Program Segment Prefix (PSP), dimana byte ke $80 menunjukan jumlah byte parameter pada command-line, dan byte ke $80 s/d $FF (127 byte) adalah Command-line yang diakhir dengan $0d. Buatlah program yang dapat membuat Subdirectori berdasarkan parameter yang dibuat user. -a 100 0B40:0100 xor bx,bx 0B40:0102 mov bl,[80] 0B40:0106 mov byte [bx+81],0 0B40:010B mov ah,39 0B40:010D mov dx,82 0B40:0110 int 21 0B40:0112 mov ah,4c 0B40:0114 int 21 0B40:0116 -n buatdir.com -rcx CX 0000 :16 -w Writing 00016 bytes -q Untuk mencobanya ketik buatdir Hello Otomatis akan terbentuk sebuah Subdirectori baru dengan nama Hello. 4. Perbaiki soal latihan no 2 dan 3 bab sebelumnya dengan kemampuan penggunakan parameter.

Hendra, MT. & Hartono, M.Kom.

34

Pemrograman Bahasa Rakitan

Bab 6, Percabangan
Program komputer umumnya terdiri dari tiga struktur dasar, yaitu urutan perintah, keputusan, dan perulangan. Suatu keputusan dilakukan untuk melakukan percabangan berdasarkan kondisi tertentu. Pada CPU 8086 menyediakan berbagai perintah untuk proses percabangan, baik yang bersifat unconditional jump maupun conditional jump.

Jump Tanpa kondisi


Perintah unconditional melakukan transfer titik eksekusi ke titik lain dengan menggunakan perintah JMP. Secara sederhana perintah JMP dapat ditulis sebagai: JMP lokasi Contoh : 0B11:0100 jmp 112 0B11:0102 db 'hello world !',0d,0a,'$' 0B11:0112 mov ah,9 0B11:0114 mov dx,102 0B11:0117 int 21 0B11:0119 mov ah,4c 0B11:011B int 21

Jump dengan kondisi


Berbeda dengan perintah JMP yang melakukan jump tanpa kondisi, perintah-perintah berikut ini melakukan jump (ke posisi -128 byte kebelakang atau 127 byte kedepan) berdasarkan kondisi. Perintah ini terbagi atas tiga kempok Jump berdasarkan bit Flag
Instruksi JZ, JE JC, JB, JNAE JS JO JPE, JP Keterangan Jump if Zero (Equal) Jump if Carry (Below, Not Above Equal) Jump if Sign Jump if Overflow Jump if Parity Even Kondisi ZF=1 CF=1 SF=1 OF=1 PF=1 Instruksi lawan JNZ, JNE JNC, JNB, JAE JNS JNO JPO

Jump untuk bilangan bertanda


Instruksi JE, JZ JNE, JNZ Keterangan Jump if Equal (=). Jump if Zero. Jump if Not Equal (<>). Kondisi ZF =1 ZF = 0 Instruksi lawan JNE, JNZ JE, JZ

Hendra, MT. & Hartono, M.Kom.

35

Pemrograman Bahasa Rakitan


Jump if Not Zero. JA , JNBE Jump if Above (>). Jump if Not Below or Equal (not <=). Jump if Below (<). Jump if Not Above or Equal (not >=). Jump if Carry. Jump if Above or Equal (>=). Jump if Not Below (not <). Jump if Not Carry. Jump if Below or Equal (<=). Jump if Not Above (not >). CF = 0 and ZF = 0 CF = 1 JNA, JBE

JB , JNAE, JC

JNB, JAE, JNC

JAE , JNB, JNC

CF = 0

JNAE, JB

JBE , JNA

CF = 1 or ZF = 1

JNBE, JA

Jump untuk bilangan bertanda


Instruksi JE , JZ JNE , JNZ JG , JNLE Keterangan Jump if Equal (=). Jump if Zero. Jump if Not Equal (<>). Jump if Not Zero. Jump if Greater (>). Jump if Not Less or Equal (not <=). Jump if Less (<). Jump if Not Greater or Equal (not >=). Jump if Greater or Equal (>=). Jump if Not Less (not <). Jump if Less or Equal (<=). Jump if Not Greater (not >). Kondisi ZF = 1 ZF = 0 ZF = 0 and SF = OF Instruksi lawan JNE, JNZ JE, JZ JNG, JLE

JL , JNGE JGE , JNL JLE , JNG

SF <> OF JNL, JGE SF = OF JNGE, JL

ZF = 1 JNLE, JG or SF <> OF

Pemakaian perintah Jumps


Misalkan anda diberi data sebagai berikut: INT 21,39 - Create Subdirectory (mkdir) AH = 39h DS:DX = pointer to ASCIIZ path name on return: CF = 0 if successful = 1 if error AX = error code (see DOS ERROR CODES) - creates specified subdirectory Hendra, MT. & Hartono, M.Kom. 36

Pemrograman Bahasa Rakitan - returns error if directory already exists, element of the path is not found, directory full or write protected disk Catatan: ASCIIZ adalah suatu string yang diakhiri dengan null (0) Untuk program jenis COM, program line parameter dapat diperoleh pada Program Segment Prefix (PSP), dimana byte ke $80 menunjukan jumlah byte parameter pada command-line, dan byte ke $80 s/d $FF (127 byte) adalah Command-line yang diakhir dengan $0d. Dan anda ditugaskan untuk membuat program yang dapat Subdirectori berdasarkan parameter yang diketikan oleh user, serta melaporkan apakah proses pembuatan Subdirectori berhasil atau tidak. Contoh: BuatDir Hello Direktori berhasil dibuat BuatDir Hello Direktori gagal dibuat -a 100 0BB0:0100 jmp 139 0BB0:0102 db 'Direktori berhasil dibuat.',0d,0a,'$' 0BB0:011F db 'Direktori gagal dibuat.',0d,0a,'$' 0BB0:0139 xor bx,bx 0BB0:013B mov bl,[80] 0BB0:013F mov byte [bx+81],0 0BB0:0144 mov ah,39 0BB0:0146 mov dx,82 0BB0:0149 int 21 0BB0:014B jc 152 0BB0:014D mov dx,102 0BB0:0150 jmp 155 0BB0:0152 mov dx,11f 0BB0:0155 mov ah,9 0BB0:0157 int 21 0BB0:0159 mov ah,4c 0BB0:015B int 21 0BB0:015D -n buatdir.com -rcx Hendra, MT. & Hartono, M.Kom. 37

Pemrograman Bahasa Rakitan CX 005C :5d -w Writing 0005D bytes -

Latihan
1. Gambarkan flowchart untuk contoh BuatDir. 2. Buatlah program yang dapat membuat Subdirectori berdasarkan parameter yang dimasukan oleh pemakai, dan menampilkan status hasil. 3. Buatlah program yang dapat menghapus Subdirectori berdasarkan parameter yang dimasukan oleh pemakai, dan menampilkan status hasil.

Hendra, MT. & Hartono, M.Kom.

38

Pemrograman Bahasa Rakitan

Bab 7, Perulangan
Untuk melakukan perulangan anda dapat menggunakan perintah LOOP. Pada dasarnya perintah LOOP adalah suatu kombinasi dari pengurangan terhadap nilai CX dan suatu jump berdasarkan kondisi, berikut ini adalah pemakaian jump untuk mensimulasikan perintah LOOP: -a 100 0B40:0100 mov cx,5 0B40:0103 mov ah,0e 0B40:0105 mov al,24 0B40:0107 int 10 0B40:0109 dec cx 0B40:010A jnz 103 0B40:010C mov ah,4c 0B40:010E int 21 0B40:0110

;cx = cx -1 dan update Flag ;jika ZF <> 0

Pada program tersebut diatas akan memberikan nilai awal 5 kepada register CX, kemudian dilakukan operasi pencetakan huruf $ dengan menggunakan fungsi teletype pada Int 10. Setelah itu nilai register CX akan dikurangi satu, setelah proses decrement, percabangan akan dilakukan kelokasi 103 jika nilai ZF=0. -a 100 0B40:0100 mov cx,5 0B40:0103 mov ah,0e 0B40:0105 mov al,24 0B40:0107 int 10 0B40:0109 loop 103 0B40:010B mov ah,4c 0B40:010D int 21 0B40:010F Pemakaian perintah Loop 103 diatas setara dengan pemakaian perintah dec cx, jnz 103.

Perulangan berdasarkan kondisi


Selain perulangan berdasarkan nilai CX, perulangan juga dapat juga berdasarkan kondisi tambahan.

Hendra, MT. & Hartono, M.Kom.

39

Pemrograman Bahasa Rakitan


Instruksi Loop LoopE LoopNE LoopNZ LoopZ JCXZ Operasi dan kondisi percabangan Instruksi lawan

Kurangi nilai cx, dan lakukan percabangan ke lokasi DEC CX dan JCXZ jika nilai cx bukan nil Kurangi nilai cx, dan lakukan percabangan ke lokasi LoopNE jika cx bukan nol dan equal (ZF=1) Kurangi nilai cx, dan lakukan percabangan ke lokasi LoopE jika cx bukan nol dan not equal (ZF=0) Kurangi nilai cx, dan lakukan percabangan ke lokasi LoopZ jika cx bukan nol dan zf=0 Kurangi nilai cx, dan lakukan percabangan kelokasi jika cx bukan nol dan zf=1 Lakukan percabangan ke lokasi jika cx adalah nol LoopNZ OR CX,CX and JNZ

Contoh: Buatlah program yang dapat menerima 5 ketikan -a 100 0B40:0100 mov cx,5 0B40:0103 mov ah,0 0B40:0105 int 16 0B40:0107 mov ah,0e 0B40:0109 int 10 0B40:010B loop 103 0B40:010D mov ah,4c 0B40:010F int 21 0B40:0111 Buatlah program yang dapat menerima maksimal 5 ketikan atau sampai pemakai menekan Enter. -a 100 0B40:0100 mov cx,5 0B40:0103 mov ah,0 0B40:0105 int 16 0B40:0107 mov ah,0e 0B40:0109 int 10 0B40:010B cmp ah,0d 0B40:010E loopne 103 0B40:0110 mov ah,4c 0B40:0112 int 21 0B40:0114

;keputusan berdasarkan cx dan ZF

Hendra, MT. & Hartono, M.Kom.

40

Pemrograman Bahasa Rakitan

Nested Loop
Nested loop dapat dilakukan dengan mendorong nilai register CX ke stack sebelum perulangan kedua dimulai, dan menarik kembali nilai CX dari stack setelah perulangan kedua selesai. Contoh: -a 100 0B40:0100 mov cx,5 0B40:0103 push cx 0B40:0104 mov cx,5 0B40:0107 mov ah,0e 0B40:0109 mov al,24 0B40:010B int 10 0B40:010D loop 107 0B40:010F mov ah,0e 0B40:0111 mov al,0d 0B40:0113 int 10 0B40:0115 mov ah,0e 0B40:0117 mov al,0a 0B40:0119 int 10 0B40:011B pop cx 0B40:011C loop 103 0B40:011E mov ah,4c 0B40:0120 int 10 0B40:0122 -

Pemanfaatan Stack
Stack adalah suatu area dari memori untuk menyimpan data sementara. Stack digunakan oleh perintah CALL untuk menyimpan alamat kembalian dari procedure, perintah RET akan mengambil nilai ini dari stack dan kembali ke lokasi offset tersebut. Demikian juga ketika perintah INT dipanggil akan menyimpan register flag, CS dan IP. Perintah IRET mengunakannya untuk kembali dari rutin interrupt handle. Kita dapat juga menggunakan stack untuk menyimpan data 16 bit dengan menggunakan perintah PUSH dan mengambil data dari stack dengan perintah POP, dengan format penulisan sebagai berikut : PUSH REG PUSH SREG PUSH memory Hendra, MT. & Hartono, M.Kom. 41

Pemrograman Bahasa Rakitan

POP REG POP SREG POP memory Sesuatu yang perlu anda ketahui adalah bahwa stack menggunakan algoritma LIFO (Last In First Out). Jika anda perlu menyimpan nilai flag ke stack, maka dapat menggunakan perintah PUSHF dan menggunakan perintah POPF untuk menarik kembali.

Latihan
1. Buatlah program yang mencetak kata Password: dan menerima maksimal 15 ketikan atau pemakai menekan Enter. Pada setiap pengetikan dicetak huruf * 2. Kembangkan program nomor satu untuk kemampuan mencetak kembali pesan Password anda : xxxxxx, dimana xxxxx adalah huruf-huruf yang diketikan oleh pemakai. 3. Kembangkan program nomor dua untuk kemampuan program untuk memeriksa password yang dimasukan adalah assembly, jika ya akan ditampilkan password anda benar, dan jika tidak akan ditampilkan password anda salah. 4. Buatlah program dengan nested loop yang dapat menampilkan 12345 12345 12345 12345 12345 54321 54321 54321 54321 54321

Hendra, MT. & Hartono, M.Kom.

42

Pemrograman Bahasa Rakitan

Bab 8, Operasi Logika


Ada empat operasi logika yang sering dilakukan, yaitu AND, OR, XOR dan NOT, dimana pada masing-masing operasi dilakukan untuk pengaturan bit pada suatu data biner.

Operasi AND
Operasi AND sering digunakan untuk operasi masking bit tertentu menjadi nol, maupun untuk mendeteksi apakah suatu bit aktif atau tidak, setelah dilakukan operasi AND, maka akan diperiksa ZF=1, jika benar artinya bit tersebut tidak aktif. Adapun operasi dari AND adalah sebagai berikut:
0 0 1 1 and and and and 0 1 0 1 = = = = 0 0 0 1

Contoh:

MOV AL, 'a' AND AL, 11011111b RET

; AL = 01100001b ; AL = 01000001b

('A')

Operasi AND juga dapat digunakan untuk menghitung sisa bagi dest := dest MOD 2n
and and and and and mov ax, ax, ax, ax, ax, ah, 3 0Fh 1Fh 3Fh 7Fh 0 ;AX := AX mod ;AX := AX mod ;AX := AX mod ;AX := AX mod ;AX := AX mod ;AX := AX mod ; (Same as ax 4 16 32 64 128 256 and 0FFh)

Operasi OR
Operasi OR sering digunakan untuk operasi masking bit tertentu menjadi satu, adapun operasi OR adalah sebagai berikut:
0 0 1 1 or or or or 0 1 0 1 = = = = 0 1 1 1

Example: Hendra, MT. & Hartono, M.Kom. 43

Pemrograman Bahasa Rakitan


MOV AL, 'A' OR AL, 00100000b RET ; AL = 01000001b ; AL = 01100001b ('a')

Perintah OR juga sering digunakan untuk memeriksa apakah suatu register berisi nilai nol. Contoh: CMP AX, 0 dapat ditulis juga OR AX, AX

Operasi XOR
Operasi OR sering digunakan untuk membalikkan kondisi bit tertentu, maupun untuk menolkan suatu register, misalnya penulisan MOV AX, 0 dapat diganti dengan XOR AX,AX,
B80000 31C0 MOV XOR AX,0000 AX,AX ;lebih efisien

Dalam hal ini XOR AX, AX lebih pendek dari pada MOV AX,0 Adapun operasi dari XOR adalah sebagai berikut :
0 0 1 1 xor xor xor xor 0 1 0 1 = = = = 0 1 1 0

Contoh:
MOV AL, 00000111b XOR AL, 00000010b RET ; AL = 00000101b

Operasi NOT
Operasi NOT digunakan untuk membuat bilangan komplemen satu yaitu membalikan keaktifkan bit, adapun operasi NOT adalah sebagai berikut:
NOT 0 = 1 NOT 1 = 0

Contoh:
MOV AL, 00011011b NOT AL ; AL = 11100100b RET

Hendra, MT. & Hartono, M.Kom.

44

Pemrograman Bahasa Rakitan

Pemakaian Operasi Logika


Operasi logika sering digunakan untuk memanipulasi status dari perangkat keras, misalnya untuk mendeteksi, mengaktifkan maupun mematikan bit-bit tertentu. Pada IBM PC Compatible data daftar peralatan dapat diperoleh dari data word di lokasi 0040:0010 pada BIOS Data Area dengan setting sebagai berikut ini: bit 0 bit 1 bit 2-3 Jika bernilai 0, artinya komputer tidak memiliki drive disket 1 berarti terdapat numeric coprocessor memori motherboard: 01=16K; 10=32K; 11=64K+ (biasanya bernilai 00 pada PC modern, sehingga tidak ada artinya) Pada PS/2, jika bit 2 bernilai 1 ketika suatu mouse terdeteksi pada saat POST bit 4-5 Video adaptor yang sedang aktif 00 = reserver, 01 = 40 clm color, 10 = 80clm color, 11 = TTL Monochrome bit 6-7 Jumlah drive disket yang terdeteksi 00=1; 01=2;10=3;11=4 bit 8 1 = hardware DMA tersedia (tidak reliable) bit 9-11 RS-232 serial port yang terdeteksi 000=0, 001=1, ... 100=4 ... 111=7 bit 12 1 = adapter game (joystick) terdeteksi oleh POST bit 13 (hanya pada PCjr) 1 = printer serial terpasang bit 14- jumlah dari port printer parallel 00=0, 01=1, 10=2, 11=3 15 Sehingga untuk mendeteksi keberadaan drive disket kita dapat melakukan operasi AND word settting tersebut diatas dengan nilai $1, jika hasil operasi tersebut not zero (zero flag), maka berarti disk drive terpasang. Untuk mendeteksi keberadaan coprocessor dapat dilakukan dengan melakukan operasi And word setting tersebut diatas dengan nilai $2.

Operasi logika pada x86


Tata cara penulisan operasi logika pada x86 dan register flag yang terpengaruh ditunjukan pada tabel berikut ini: Format instruksi AND dest, src OR dest, src XOR dest, src NOT dest TEST dest, src Fungsi operasi logika and dari dua operand, dan mengembalikan hasil pada dest. operasi logika or dari dua operand, dan mengembalikan hasil pada dest. operasi logika or dari dua operand, dan mengembalikan hasil pada dest. mengembalikan invers bit pada dest melakukan operasi AND dari dua operand dan mengupdate register Flags terpengaruh CF, OF, PF, SF, ZF (AF tak terdefinisi) CF, OF, PF, SF, ZF (AF tak terdefinisi) CF, OF, PF, SF, ZF (AF tak terdefinisi) CF, OF, PF, SF, ZF (AF tak terdefinisi) 45

Hendra, MT. & Hartono, M.Kom.

Pemrograman Bahasa Rakitan flag, tetapi tidak mengembalikan hasil pada dest. -a 100 0B46:0100 mov ax,0040 0B46:0103 mov ds,ax 0B46:0105 mov ax,[0010] 0B46:0108 and ax,1 0B46:010B -t AX=0040 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=0B46 ES=0B46 SS=0B46 CS=0B46 IP=0103 NV UP EI PL NZ NA PO NC 0B46:0103 8ED8 MOV DS,AX -t AX=0040 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=0040 ES=0B46 SS=0B46 CS=0B46 IP=0105 NV UP EI PL NZ NA PO NC 0B46:0105 A11000 MOV AX,[0010] DS:0010=C822 -t AX=C822 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=0040 ES=0B46 SS=0B46 CS=0B46 IP=0108 NV UP EI PL NZ NA PO NC 0B46:0108 250100 AND AX,0001 -t AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=0040 ES=0B46 SS=0B46 CS=0B46 IP=010B NV UP EI PL ZR NA PE NC Operasi tersebut diatas dapat dijelaskan bahwa pada awalnya akan diduplikasi nilai 0040 ke register AX, kemudian nilai dari register AX akan diduplikasi ke register DS, dan akan diduplikasi nilai dari lokasi memori 0040:0010 ke register AX, dan kemudian akan dilakukan operasi AND register AX dengan nilai $1. Berdasarkan hasil T (Trace) yang dilakukan terlihat bahwa hasil akhir register AX adalah 0000 dan ZR (Zero flag aktif), berarti bahwa tidak ada drive disket yang terpasang.
org 100h push ds mov ax,40h mov ds,ax mov ax,[10h] pop ds

Hendra, MT. & Hartono, M.Kom.

46

Pemrograman Bahasa Rakitan


and ax,2h jz cetak_tidak_ada mov dx, offset ada jmp cetak cetak_tidak_ada: mov dx, offset tidak_ada cetak: mov ah,9h int 21h mov ah,4ch int 21h ada db 'ada coprocessor.',0dh,0ah,'$' tidak_ada db 'tidak ada coprocessor.',0dh,0ah,'$'

Adapun program tersebut diatas dapat dijelaskan bahwa pada awalnya akan didorong nilai register DS ke stack, kemudian duplikasi nilai 40 ke register AX, kemudian diduplikasi nilai AX ke DS, kemudian diduplikasi isi memori yang ditunjuk oleh DS: [0010] dalam hal ini adalah 0040:1000 ke register AX, dan kemudian register AX di AND dengan nilai $2, dan tarik kembali nilai dari stack ke register DS, berdasarkan hasil operasi AND akan diuji nilai Zero flag, jika aktif akan dicetak tidak ada coprocessor dan sebaliknya akan dicetak ada coprocessor. Sesuatu hal yang perlu diingat bahwa perintah TEST tidak menyimpan nilai hasil operasi, tetapi hanya mempengaruhi flag. Perintah test dapat digunakan untuk memeriksa apakah suatu register bernilai nol atau tidak, contoh: Sesuatu hal yang perlu diingat bahwa operasi TEST tidak menyimpan nilai hasil operasi, tetapi hanya mempengaruhi flag. Test dapat digunakan untuk memeriksa apakah suatu register bernilai nol atau tidak.
85C0 3D0000 TEST CMP AX,AX AX,0000

Dalam hal ini TEST AX,AX lebih pendek dibandingkan dengan CMP AX,AX.

Latihan
Byte pada 0040:0017 pada BIOS Data Area menunjukan status keyboard sebagai berikut ini : bit 0 Status shift sebelah kanan ditekan 47

Hendra, MT. & Hartono, M.Kom.

Pemrograman Bahasa Rakitan 1 2 3 4 5 6 7 shift sebelah kiri ditekan ctrl ditekan alt ditekan keaktifkan ScrollLock keaktifan NumLock keaktifkan CapsLock Keaktifan Insert 1. Buatlah program Assembly yang dapat menampilkan pesan keaktifan tombol CapsLock (CapsLock Aktif, CapsLock tidak Aktif). 2. Buatlah program Assembly yang menon-aktifkan tombol Capslock 3. Buatlah program Assembly yang mengaktifkan tombol NumLock 4. Buatlah program Assembly yang dapat membalikkan status tombol Capslock (On menjadi Off dan sebaliknya). 5. Modifikasi soal latihan nomor tiga bab sebelumnya agar password yang dimasukan tidak case sensitif.

Hendra, MT. & Hartono, M.Kom.

48

Pemrograman Bahasa Rakitan

Quiz
CGA video memori untuk text mode terdapat dilokasi memori B800:0000 s/d B800:0F9F untuk halaman pertama. Masing-masing karakter yang ditampilkan pada layar terdiri dari menggunakan satu WORD, yaitu low byte adalah nilai ASCII dari karakter, dan high byte adalah atribut (background dan foreground). Misalnya pada posisi baris 0, kolom 0 ditampilkan huruf A dengan warna latarbelakang black dan warna tulisan light gray, maka isi memori B800:0000 adalah $41 dan isi memori B800:0001 adalah $07. 1. Buatlah program yang dapat mengubah atribut layar menjadi latarbelakang merah dan warna tulisan light gray tanpa mengubah tulisan yang ada. 2. Buatlah program yang dapat mengubah karakter pada layar menjadi huruf besar semua. 3. Buatlah program yang dapat mengubah karakter pada layar menjadi huruf kecil semua. 4. Dengan menggunakan nested loop, buatlah program yang dapat menampilkan urutan angka berikut : 12345 54321 1234 5432 123 543 12 54 1 5 6. Buatlah program yang dapat menampilkan suatu daftar ASCII dengan tampilan sebagai berikut:

Hendra, MT. & Hartono, M.Kom.

49

Pemrograman Bahasa Rakitan

Bab 9, Operasi String


Pada prinsipnya data string direpresentasikan sebagai urutan data byte pada suatu lokasi dimemori yang pada DOS diakhir dengan tanda end of string '$' (pemakaian int $21, AH= $9), maupun diakhir dengan tanda ASCIIZ atau null. Pada 8086 tidak spesifik menentukan penanda dari akhir string, dan dalam hal ini ditentukan sendiri oleh programmer, tetapi menyediakan beberapa perintah untuk memudahkan membandingkan nilai register dengan isi memori, membandingkan memori dengan memori, menduplikasi memori ke memori, dan menduplikasi nilai register ke memori. Perintah-perintah ini dapat bekerja secara per-Byte maupun per-Word. Operasi pengolahan string ini bekerja dengan menggunakan register index (SI dan DI) sebagai offset pointer, dan register DS dan ES sebagai pointer ke segment dimana data berada. Secara umum pasangan yang digunakan adalah DS:[SI] untuk sumber data, dan ES:[DI] untuk target data. Operasi per-Byte akan secara menaikan/menurunkan nilai register SI atau DI ataupun keduanya (tergantung kepada jenis operasi yang dilakukan) dengan nilai satu , sedangkan untuk operasi per-Word akan menaikan/menurunkan nilai register index dengan dua. Operasi akan menaikan nilai register index jika DF=0, dan operasi akan akan menurunkan nilai index jika DF=1.

Mengatur Direction Flag


Sebagaimana dijelaskan bahwa operasi string mempengaruhi nilai register index, dengan menambah atau mengurangi tergantung kepada satus dari Direction Flag (DF), adapun perintah yang dapat digunakan untuk men-set DF=1 adalah STD, dan men-clear DF=0 adalah CLD.

Membandingkan Register dengan Memori


Untuk membandingkan register dengan memori dapat menggunakan perintah SCASB maupun SCASW, perintah SCASB membandingkan nilai AL terhadap ES:[DI], sedangkan perintah SCASW membandingkan nilai AX terhadap ES:[DI]. Hasil perbandingan dapat dilihat pada flag OF, SF, ZF, AF, PF, dan CF. Kemudian dilakukan update nilai DI.

Membandingkan Memori dengan Memori


Untuk membandingkan memori dengan memori dapat menggunakan perintah CMPSB (per-Byte) maupun CMPSW (per-Word), perintah ini membandingkan nilai antara DS: [SI] terhadap ES:[DI], hasil perbandingan dapat dilihat pada flag OF, SF, ZF, AF, PF, dan Hendra, MT. & Hartono, M.Kom. 50

Pemrograman Bahasa Rakitan CF. Kemudian dilakukan update nilai DI dan SI.

Menduplikasi nilai Register ke Memori


Untuk menduplikasi nilai register AL ke ES:[DI] dapat menggunakan perintah STOSB, dan nilai register AX ke ES:[DI] dengan perintah STOSW. Perintah ini secara otomatis mengupdate nilai DI.

Menduplikasi Memori ke Memori


Untuk menduplikasi nilai DS:[SI] ke ES:[DI] dapat menggunakan perintah MOVSB maupun MOVSW. Perintah MOVSB bekerja secara Byte, dan MOVSW bekerja secara Word. Perintah ini secara otomatis akan mengupdate nilai SI dan DI.

Menduplikasi nilai Memori ke Register


Untuk menduplikasi nilai dari DS:[SI] ke register AL dapat menggunakan perintah LODSB, dan nilai dari DS:[SI] ke register AX menggunakan perintah LODSW. Perintah ini secara otomatis menaikan nilai SI.

Perintah Perulangan
Pada operasi string sering dilakukan secara per-blok untuk sejumlah byte ataupun word, sehingga perintah yang ada perlu diulangi sejumlah kali operasi. Adapun perintah perulangan dan aturannya disajikan pada tabel sebagai berikut: Perintah REP REPE/REPZ Fungsi Mengulangi perintah movsb, movsw, lodsb, lodsw, stosb, stosw sebanyak nilai CX Mengulangi perintah cmpsb, cmpsw, scasb, scasw ketika nilai ZF=1, dan maksimun sebanyak nilai CX CX <> 0 ZF = 1 AND CX <> 0 ZF = 0 AND CX <> 0

REPNE/REPNZ Mengulangi perintah cmpsb, cmpsw, scasb, scasw ketika nilai ZF=0, dan maksimun sebanyak nilai CX Contoh pemakaian: .model tiny .code Hendra, MT. & Hartono, M.Kom.

51

Pemrograman Bahasa Rakitan org 100h utama: mov ah,9h mov dx,offset pesanAwal int 21h mov cx,14 push ds pop es cld mov di, offset bacaString prosesBaca: mov ah,0 int 16h cmp al,0dh jz periksaPassword stosb mov ah,0eh mov al,'*' int 10h loop prosesBaca periksaPassword: mov si,offset bacaString mov di,offset passWord mov cx,15 repz cmpsb jnz cetakSalah mov dx, offset pesanBenar jmp prosesCetak cetakSalah: mov dx, offset pesanSalah prosesCetak: Hendra, MT. & Hartono, M.Kom. 52 ;membanding DS:[SI] dengan ES:[DI] --> 15 byte ;tidak sama goto cetakSalah ;sesuai dengan panjang pass ;es = ds ;clear DF

;baca keystroke --> al ;jika enter goto periksaPassword ;al --> ES:[DI]

;cetak * ;CX=CX-1; ulangi ketika CX <> 0

Pemrograman Bahasa Rakitan mov ah,9h int 21h

;cetak sesuai nilai DX

mov ah,4ch int 21h pesanAwal db 0dh,0ah,"ketik password:$" bacaString db 15 dup(0) passWord db "hendrasoewarno",0 pesanSalah db 0dh,0ah,"password salah!",0dh,0ah,"$" pesanBenar db 0dh,0ah,"password benar!",0dh,0ah,"$" end utama

Menggunakan Assembler
Mulai bab ini kita akan menampilkan source code dalam format assembler seperti TASM, MASM, FASM, dan anda dapat juga menggunakan emu8086. Sesuatu hal yang perlu diperhatikan, pada software assembler mewajibkan kita mengetik instruksi didalam struktur tertentu dan diawali dengan directive tertentu, karena software assembler dapat mendukung berbagai target model memori (TINY, SMALL, COMPACT, MEDIUM, LARGE, HUGE, atau FLAT, yang mempengaruhi ukuran program dan data pointer), dan format executable (COM atau EXE). Sesuatu hal yang perlu diperhatikan didalam penulisan bilangan pada program Assembler jika tidak diakhir dengan huruf h, maka akan dianggap sebagai bilangan desimal (basis 10).
format Executable COM .model tiny .code org 100h utama: format Executable EXE dosseg .model small .stack 100h .code main proc mov mov mov mov int mov int ax,@data ds,ax ah,9h dx,offset pesan 21h ah,4ch 21h

mov mov int mov int

ah,09 dx,offset pesan 21h ah,4ch 21h

main endp pesan db "hello world!$" end utama .data pesan db "hello world!$" end

Hendra, MT. & Hartono, M.Kom.

53

Pemrograman Bahasa Rakitan Adapun beberapa keuntungan menggunakan Assembler dibandingkan dengan Debug : 1. Pengetikan program Assembly dapat menggunakan text Editor 2. Dapat menggunakan label untuk pengalamatan sehingga tidak diperlukan perhitungan offset alamat dengan secara manual 3. Perbaikan program yang lebih mudah (cukup diperbaiki di sourcecode dan di Assembler ulang).

Model Memori
Model memori tradisional dikenali oleh banyak bahasa pemrograman seperti small, medium, compact, large dan huge (ini menjadi penting bila anda menghubungkan antara program ASM dengan suatu bahasa tingkat tinggi, lihat lampiran D) Model Small mendukung satu data segment dan satu code segment, dan secara default semua data dan koding adalah NEAR. Model Large mendukung banyak data segment dan codesegment, semua data dan koding adalah FAR. Model Medium mendukung satu data segment dan banyak code segment. Model Compact mendukung banyak data segmetn dan satu code segment. Model Huge memungkinkan satu data tunggal dapat lebih besar dari satu segment, tetapi implementasi dari item data besar tersebut harus dikodekan oleh programmer. Model Tiny hanya berjalan dibawah MS-DOS, model tiny menempatkan semua data dan kode pada satu segment yang sama, sehingga total data + kode tidak boleh lebih besar dari 64 Kb.

Pada masing-masing model, anda dapat mengatur pointer secara manual dengan menulikan sebagai NEAR atau FAR.

Memori Flat
Memori Flat adalah konfigurasi yang tidak tersegmentasi dan hanya tersedia pada sistim operasi 32 bit. Model memori Flat menyerupai model tiny dimana semua kode dan data berada pada suatu pengalamatan tunggal 32-bit. Penulisan untuk program model Flat adalah menggunakan directive sebagai berikut:
.386 .MODEL FLAT ; All data and code, including system resources, are in a single 32-bit segment.

Hendra, MT. & Hartono, M.Kom.

54

Pemrograman Bahasa Rakitan

Proses Assembler
Program tersebut adalah executable COM, dan proses assembler melalui dua tahapan yaitu proses assembler itu sendiri dan proses link, dengan contoh sebagai berikut: TASM password.asm TLINK password /x /t

FASM (Fast Assembler)


Selain TASM dan MASM, anda dapat juga menggunakan paket Assembler lainnya yaitu FASM, pemakaian FASM lebih sederhana, berikut ini contoh program Hello World untuk executable COM dan EXE.
Format executable COM org 100h format executable EXE format MZ entry code_seg:start stack 100h segment code_seg start: mov ax,data_seg mov ds,ax mov ah,9h mov dx,pesan int 21h mov ax,4C00h int 21h segment data_seg pesan db 'Hello world!',24h

mov mov int mov int

ah,9h dx,pesan 21h ah,4ch 21h

pesan db "hello world!$"

Untuk proses assembler dengan Fast Assembler FASM hello.asm

Emulator8086
Emulator adalah suatu lingkungan tiruan yang menyerupai lingkungan sebenarnya. Emu8086 adalah software emulator yang mensimulasikan lingkungan CPU 8086 dan sebagian sistim operasi DOS (tidak semua interrupt tersedia). Untuk proses pembelajaran, emulator cenderung lebih mudah digunakan dibandingkan dengan DEBUG.EXE maupun Assembler, karena pada saat eksekusi program dijalankan pada suatu lingkungan virtual sehingga kesalahan program tidak menyebabkan gangguan pada sistim secara keseluruhan. Hendra, MT. & Hartono, M.Kom. 55

Pemrograman Bahasa Rakitan

Anda dapat mendonwload software emu8086 untuk percobaan 14 hari pada http://www.emu8086.com.

Latihan
1. Buatlah program yang dapat menerima maksimum 10 karakter dan dapat diakhir dengan Enter, dan karakter yang dapat diketik dibatasi yang berada pada nama anda. 2. Simpanlah isi layar text mode halaman pertama ke halaman kedua dengan akses langsung CGA video memori pada alamat $B800:0000 ke $B800:0FA0, sebanyak 4000 byte. Kemudian terima ketikan satu karakter dari user dan mencetak ke halaman pertama layar dengan akses langsung ke memori dengan background merah dan foreground light gray, kemudian jika pemakaian menekan sembarang tombol, kembalikan isi layar yang disimpan sebelumnya. 3. Buatlah program yang meminta pemakai memasukan password, dan menampilkan password tersebut benar atau tidak. 4. Perbaiki program soal nomor tiga agar password yang dimasukan tidak case sensitif. Catatan: Buatlah program dengan model COM.

Hendra, MT. & Hartono, M.Kom.

56

Pemrograman Bahasa Rakitan

Bab 10, Operasi Shift dan Rotasi


Salah satu fungsi utama dari pemakaian shift dan rotasi adalah untuk packing dan unpacking data. Jika data yang anda simpan lebih kecil dari 8-bit maupun 16-bit, maka pemakaian byte maupun word untuk menyimpan data anda tentu saja memboroskan, Misalnya kita perhatikan kembali BIOS Data area, dimana suatu byte 0040:0017 digunakan untuk menunjukan status On/Off dari shift kiri, shift kanan, ctrl, alt, scrollLock, numLock, capsLock, insert. Jika masing-masing status menggunakan 1 byte, maka diperlukan 8 byte, tetapi karena kondisi yang direpresentasikan adalah On/Off, maka pemakaian masing-masing bit dalam satu byte cukup untuk menyimpan status keyboard tersebut (hal inilah yang disebut sebagai packing data). Pemakaian lain dari perintah rotasi adalah untuk enkripsi dan dekripsi data. Contoh: mov al, 41h rol al,1 ror al,1 ; 1000001b adalah ascii dari karakter A ; 0000011b telah menjadi karakter ascii lain ; 1000001b telah kembali menjadi karakter A

Perintah Shift (SHL, SHR, SAL, SAR) juga sering digunakan untuk manipulasi data perkalian dan pembagian bulat 2n. Contoh: mov al, 2 shl al,1 shr al,1 ; 00000010b ; al = 4 = 00000100b ; al = 2 = 00000010b

Pemakaian SAL adalah sama dengan SHR, dan SAR digunakan untuk pembagian bilangan bertanda..

SHL (Shift Left)


Melakukan shift semua bit ke kiri, bit yang keluar dimasukan ke CF, dan bit nol disisipkan pada posisi LSB.

Adapun sintak penulisan untuk SHL adalah sebagai berikut:


shl shl op, 1 op, CL

Hendra, MT. & Hartono, M.Kom.

57

Pemrograman Bahasa Rakitan Dalam hal ini op adalah register atau memori, dan perintah ini mempengaruhi OF, SF, ZF, AF=?, PF, CF, flag OF = 0 jika tanda pada operand tidak berubah.
Contoh: MOV AL, 11100000b SHL AL, 1 ; AL = 11000000b,

CF=1.

SHR (Shift Right)


Melakukan shift semua bit ke kanan, bit yang keluar dimasukan ke CF, dan bit nol disisipkan pada posisi MSB.

Adapun sintak penulisan untuk SHR adalah sebagai berikut:


shr shr op, 1 op, CL

Dalam hal ini op adalah register atau memori, flag OF = 0 jika tanda pada operand tidak berubah.
Contoh: MOV AL, 00000111b SHR AL, 1 ; AL = 00000011b,

CF=1.

SAL (Shift Arithmetic Left)


Melakukan shift semua bit ke kiri, bit yang keluar dimasukan ke CF, bit nol disisipkan pada LSB (Sama seperti SHL)

Adapun sintak penulisan untuk SAL adalah sebagai berikut:


sal sal op, 1 op, CL

Dalam hal ini op adalah register atau memori, flag OF = 0 jika tanda pada operand tidak berubah.
Contoh: MOV AL, 0E0h SAL AL, 1 RET ; AL = 11100000b ; AL = 11000000b,

CF=1.

Hendra, MT. & Hartono, M.Kom.

58

Pemrograman Bahasa Rakitan

SAR (Shift Arithmetic Right)


Melakukan shift semua bit ke sebelah kanan, bit yang keluar akan dimasukan ke CF, dan bit tanda yang disisipkan ke MSB akan memiliki nilai yang sama sebelum shift.

Adapun sintak penulisan untuk SAR adalah sebagai berikut:


sar sar op, 1 op, CL

Dalam hal ini op adalah register atau memori, flag OF = 0 jika tanda pada operand tidak berubah. Contoh:
MOV SAR MOV SAR AL, AL, BL, BL, 0E0h 1 4Ch 1 ; ; ; ; AL AL BL BL = = = = 11100000b 11110000b, 01001100b 00100110b, CF=0. CF=0.

ROL (Rotate Left)


Melakukan shift semua bit ke sebelah kiri, bit yang keluar akan dimasukan ke CF, dan bit yang sama disisipkan ke LSB.

Adapun sintak penulisan untuk ROL adalah sebagai berikut:


rol rol op, 1 op, CL

Dalam hal ini op adalah register atau memori, flag OF = 0 jika tanda pada operand tidak berubah. Contoh:
MOV AL, 1Ch ROL AL, 1 RET ; AL = 00011100b ; AL = 00111000b,

CF=0.

ROR (Rotate Right)


Melakukan shift semua bit ke kanan, bit yang keluar dimasukan ke flag CF dan bit yang sama disisipkan ke MSB. Hendra, MT. & Hartono, M.Kom. 59

Pemrograman Bahasa Rakitan

Adapun sintak penulisan untuk ROR adalah sebagai berikut:


ror ror op, 1 op, CL

Dalam hal ini op adalah register atau memori, flag OF = 0 jika tanda pada operand tidak berubah. Contoh:
MOV AL, 1Ch ROR AL, 1 RET ; AL = 00011100b ; AL = 00001110b, CF=0.

RCL (Rotate with Carry Left)


Melakukan shift semua bit ke kiri, bit yang keluar dimasukan ke CF dan nilai dari CF yang sebelumnya dimasukan ke LSB.

Adapun sintak penulisan untuk RCL adalah sebagai berikut:


rcl rcl op, 1 op, CL

Dalam hal ini op adalah register atau memori, flag OF = 0 jika tanda pada operand tidak berubah. Contoh:
STC MOV AL, 1Ch RCL AL, 1 RET ; set carry (CF=1) ; AL = 00011100b ; AL = 00111001b, CF=0.

RCR (Rotate with Carry Right)


Melakukan shift semua bit ke kanan, bit yang keluar dimasukan ke flag CF, dan nilai CF yang sebelumnya disisipan pada LSB.

Hendra, MT. & Hartono, M.Kom.

60

Pemrograman Bahasa Rakitan

Adapun sintak penulisan untuk RCR adalah sebagai berikut:


rcr rcr op, 1 op, CL

Dalam hal ini op adalah register atau memori, flag OF = 0 jika tanda pada operand tidak berubah. Contoh:
STC MOV AL, 1Ch RCR AL, 1 RET dosseg .model small .stack 100h .data hexaDigit db '01234567890ABCDEF' pesan1 db 0dh,0ah,"ketik plaintext:$" pesan2 db 0dh,0ah,"ciphertext:$" panjang db 0 baca .code main proc mov ax,@data mov ds,ax mov ah,9h mov dx,offset pesan1 int 21h push ds pop es mov di,offset baca cld mov panjang,0 ;clear DF db 15 dup(0) ; set carry (CF=1). ; AL = 00011100b ; AL = 10001110b, CF=0.

;arahkan ds ke data segment ;cetak ketik plaintext

Hendra, MT. & Hartono, M.Kom.

61

Pemrograman Bahasa Rakitan


mov cx, 15 ulangBaca: mov ah, 0 int 16h cmp al,0dh jz keluarBaca stosb mov ah,0eh int 10h inc panjang loop ulangBaca keluarBaca: mov ah,9h mov dx,offset pesan2 int 21h mov bx, offset hexaDigit mov si, offset baca mov cl, 0 ulangEnkrip: inc cl lodsb rol al,cl push ax and al, 11110000b shr al, 4 xlatb mov ah,0eh int 10h pop ax and al, 00001111b xlatb mov ah,0eh int 10h cmp cl, panjang jb ulangEnkrip

;baca keystroke ;jika enter keluar ;al --> ES:[DI] ;cetak nilai al ;panjang=panjang + 1 ;CX = CX -1; ulang ketika CX <> 0

;cl = 0 ;cl = cl + 1 ;ds:[si] --> al ;rotasi ke kiri sesuai nilai cl ;simpan nilai ax ;masking bit ;11110000 --> 00001111 ;al = ds:[bx+al] ;cetak al ;ambil nilai ax ;masking bit

;cetak al ;ulang ketika cl < panjang

Hendra, MT. & Hartono, M.Kom.

62

Pemrograman Bahasa Rakitan


main endp end

Program tersebut adalah executable EXE, dan proses assembler adalah sebagai berikut: TASM enkrip.asm TLINK enkrip

Latihan
1. Buatlah program yang dapat menampilkan nilai biner dari byte yang terdapat pada BIOS Data Area 0040:0017. 2. Buatlah program yang dapat menampilkan nilai octal dari byte yang terdapat pada BIOS Data Area 0040:0017. 3. Buatlah program yang dapat menampilkan nilai hexa dari byte yang terdapat pada BIOS Data Area 0040:0017. 4. Buatlah program yang dapat menerima sebuah string, dan mencetak kembali nilai hexa dari masing-masing byte pada string setelah mengalami rotasi sesuai posisi masing-masing byte (byte terenkripsi). 5. Aplikasikan byte terenkripsi tersebut pada program password pada bab sebelumnya sehingga password tidak dapat terbaca langsung pada program. 6. Buatlah program yang dapat menampilkan konfigurasi hardware berdasarkan unpacking data word dari BIOS Data Area 0040:0010. Floopy Drive : ada CoProcessor : ada Disk Drive : 0 RS-232 Port : 4 Game Adapter : 0 Parallel Port : 0

Hendra, MT. & Hartono, M.Kom.

63

Pemrograman Bahasa Rakitan

Bab 11, Operasi Aritmatika


CPU 8086 menyediakan beberapa perintah operasi artimatika untuk proses penjumlahan, pengurangan, perkalian dan pembagian.

Operasi Penjumlahan
Operasi penjumlahan menggunakan perintah ADD yang memiliki sintak penulisan sebagai berikut: add dest, src

dimana dest dan src berupa : REG, memory memory, REG REG, REG memory, immediate REG, immediate Adapun operasi yang dilakukan adalah dest = dest + src, dan akan mempengaruhi flag OF, SF, ZF, AF, PF, CF.

Operasi Pengurangan
Operasi pengurangan menggunakan perintah SUB yang memiliki sintak penulisan sebagai berikut: sub dest, src

dimana dest dan src berupa : REG, memory memory, REG REG, REG memory, immediate REG, immediate Adapun operasi yang dilakukan adalah dest = dest src, dan akan mempengaruhi flag OF, SF, ZF, AF, PF, CF.

Hendra, MT. & Hartono, M.Kom.

64

Pemrograman Bahasa Rakitan

Operasi Penjumlahan dengan Carry Flag


Operasi penjumlahan dengan perintah ADC adalah sama dengan perintah ADD ditambah lagi dengan nilai CF, sehingga operasi yang dilakukan adalah dest = dest + src + CF. Contoh:
STC MOV AL, 5 ADC AL, 1 RET ; set CF = 1 ; AL = 5 ; AL = 7

Operasi Pengurangan dengan Borrow


Operasi pengurangan dengan perintah SBB adalah sama dengan perintah SUB dikurangi lagi dengan nilai CF, sehingga operasi yang dilakukan adalah dest = dest src CF. Contoh:
STC MOV AL, 5 SBB AL, 3

; AL = 5 - 3 - 1 = 1

Operasi Perkalian
Operasi perkalian menggunakan perintah MUL yang memiliki operand berupa register ataupun memori. Jika operand adalah byte, maka operasi yang dilakukan adalah AX = AL * operand, sedangkan jika operand adalah word, maka operasi yang dilakukan adalah (DX AX) = AX * operand. Adapun flag yang dipengaruhi adalah OF, dan CF. Contoh:
MOV AL, 200 MOV BL, 4 MUL BL ; AL = 0C8h ; AX = 0320h (800)

Operasi Pembagian
Operasi pembagian menggunakan perintah DIV yang memiliki operand berupa register ataupun memori. Jika operand adalah byte, maka operasi yang dilakukan adalah AL = AX / operand, dan AH berisi sisi bagi (modulus), sedangkan jika operand adalah word, maka operasi yang dilakukan adalah AX = (DX AX) / operand, dan DX adalah berisi modulus. Contoh:
MOV AX, 203 ; AX = 00CBh

Hendra, MT. & Hartono, M.Kom.

65

Pemrograman Bahasa Rakitan


MOV BL, 4 DIV BL RET ; AL = 50 (32h), AH = 3

Perkalian bertanda
Jika anda bekerja dengan bilangan bertanda (signed), maka perintah yang digunakan untuk perkalian adalah IMUL menggantikan MUL. Contoh:
MOV AL, -2 MOV BL, -4 IMUL BL RET ; AX = 8

Pembagian bertanda
Jika anda bekerja dengan bilangan bertanda (signed), maka perintah yang digunakan untuk pembagian adalah IDIV menggantikan DIV. Contoh:
MOV AX, -203 ; AX = 0FF35h MOV BL, 4 IDIV BL ; AL = -50 (0CEh), AH = -3 (0FDh)

Operasi Negatif
Untuk melakukan operasi negatif komplemen dua dapat menggunakan perintah NEG. Adapun operasi yang dilakukan adalah melakukan invers (NOT) terhadap semua bit dan menambahkan dengan satu. Contoh:
MOV AL, 5 NEG AL NEG AL ; AL = 05h ; AL = 0FBh (-5) ; AL = 05h (5)

Program ini akan melakukan konversi suatu string ASCIIZ ke numerik yang disimpan pada variable hasil.
.model small .stack 100h .data string db '-32767',0 negatif db 0 hasil dw 0 ;string ASCIIZ

Hendra, MT. & Hartono, M.Kom.

66

Pemrograman Bahasa Rakitan


.code main proc mov ax,@data mov ds,ax xor hasil,0 mov cx,5 cld mov si, offset string ulangKonversi: xor ax,ax lodsb or al,al jz keluarKonversi cmp jnz mov jmp al,'-' bukanNegatif negatif,1 prosesBerikutnya ;jika ketemu ASCIIZ ;pastikan ax = 0

bukanNegatif: sub al,30h push ax mov ax, hasil mov bx, 0ah mul bx mov hasil,ax pop ax add hasil,ax prosesBerikutnya: loop ulangKonversi keluarKonversi: cmp negatif,1 jnz bilanganPositif neg word ptr hasil ;konversi ke negatif ;ASCII 0=30h

;bl = 10 ;(dx ax) = ax * bx

Hendra, MT. & Hartono, M.Kom.

67

Pemrograman Bahasa Rakitan


bilanganPositif: ;proses lainnya ketik disini main endp end

Latihan
1. Buatlah program yang mencetak bilangan biner dari suatu byte dengan metode pembagian. 2. Buatlah program yang mencetak bilangan octal dari suatu byte dengan metode pembagian. 3. Buatlah program yang mencetak bilangan hexa dari suatu byte dengan metode pembagian. 4. Buatlah program yang dapat mengkonversi dari string ke numerik dengan memperhatikan tanda. 5. Buatlah program yang dapat mengkonversi dari numerik ke string dengan memperhatikan tanda.

Hendra, MT. & Hartono, M.Kom.

68

Pemrograman Bahasa Rakitan

Bab 12, Makro


Makro adalah fasilitas yang disediakan oleh Assembler (bukan CPU) yang berfungsi sebagai shorcut didalam pembuatan program. Didalam pengembangan program assembly, tidak jarang kita menggunakan sejumlah proses yang sama dan hanya berbeda dari segi parameter tertentu saja, sehingga adalah lebih efisien untuk dijadikan sebagai sebuah makro beserta parameternya.Makro hanya di source code, tetapi setelah proses assembler masing-masing makro akan diganti dengan kumpulan instruksi yang sebenarnya. Manfaat Makro: 1. Mengurangi pengetikan 2. Memudahkan pembacaan program 3. Memudahkan penanganan program 4. Mengurangi tingkat kesalahan Keuntungan lain dari pemanfaatan makro adalah anda dapat membuat sebuah file yang berisi makro-makro yang sering digunakan, dan setiap kali program assembly anda membutuhkan makro yang sama, anda cukup mengikutsertakan file makro tersebut kedalam program anda. Contoh: include emu8086.inc Dimana emu8086.inc adalah kumpulan makro yang disediakan oleh aplikasi emu8086.

Pemakaian Makro
Untuk mendefinisikan suatu makro dapat mengunakan struktur sebagai berikut: nama_makro MACRO [parameter, ] instruksi ... EndM Suatu makro harus didefinisikan diatas program yang akan menggunakannya. Contoh:
exitToDos MACRO mov ah,4ch int 21h endM

Hendra, MT. & Hartono, M.Kom.

69

Pemrograman Bahasa Rakitan


cetakPesan MACRO pesan mov ah,9h mov dx,offset pesan int 21h endM cetakDigit MACRO mov ah,0eh int 10h endM barisBaru MACRO mov al,0dh cetakDigit mov al,0ah cetakDigit endM org 100h cetakPesan hello1 barisBaru cetakPesan hello2 barisBaru exitToDos hello1 db Hello Assembly!,$ hello2 db Hello Makro!,$

setelah diAssembler maka program diatas akan dikembangkan menjadi:


org mov mov int 100h ah,9h dx, offset hello1 21h mov al,0dh mov ah,0eh int 10h mov al,0ah mov ah,0eh int 10h ah,9h dx, offset hello2 21h mov al,0dh mov ah,0eh int 10h mov al,0ah mov ah,0eh int 10h ah,4ch ;ekspansi dari cetakPesan hello1 ;ekspansi dari barisBaru ;ekspansi dari cetakDigit ;ekspansi dari barisBaru ;ekspansi dari cetakDigit

mov mov int

mov

Hendra, MT. & Hartono, M.Kom.

70

Pemrograman Bahasa Rakitan


int 21h

Percabangan didalam Makro


Jika anda membuat percabangan didalam makro, maka perlu diingat bahwa setiap label yang digunakan harus ditandai sebagai LOCAL. Contoh:
;makroLib.inc exitToDos MACRO mov ah,4ch int 21h endM cetakPesan MACRO pesan mov ah,9h mov dx,offset pesan int 21h endM cetakDigit MACRO mov ah,0eh int 10h endM barisBaru MACRO mov al,0dh cetakDigit mov al,0ah cetakDigit endM ;exit to DOS

;print until eos $

;teletype

;CR ;LF

bacaDigit MACRO local mulaiBaca,periksaTanda, periksaDigit, cetakKeLayar, keluarBaca mulaiBaca: mov ah,0h int 16h cmp jnz xor jmp al,0dh periksaTanda al,al keluarBaca ;get keystroke from keyboard --> AL

;jika bukan CR ;al = 0 ;akhir pembacaan (CR = selesai)

periksaTanda: cmp al,'-' jnz periksaDigit jmp cetakKeLayar

;jika bukan tanda negatif

Hendra, MT. & Hartono, M.Kom.

71

Pemrograman Bahasa Rakitan


periksaDigit: cmp al,'0' jb mulaiBaca cmp al,'9' jg mulaiBaca cetakKeLayar: cetakDigit keluarBaca: endM bacaNumerik MACRO hasil local mulaiBaca, periksaTanda, prosesDigit, bacaBerikutnya, konversiSigned, selesaiBaca mov bp,sp push 0 mov hasil,0 mov cx,5 mulaiBaca: push cx bacaDigit or al,al jnz periksaTanda pop cx jmp konversiSigned periksaTanda: cmp al,'-' jnz prosesDigit mov [bp],1 pop cx jmp mulaiBaca prosesDigit: xor ah,ah sub al,30h push ax mov ax,hasil mov bx,0ah mul bx ;pada baca Digit CR --> AL = 0 ;lanjut ke pemeriksaan tanda ;buat satu variabel local, flag tanda ;hasil = 0 ;maksimal 5 digit ;simpan cx ke stak

;dibawah ASCII 0 ;diatas ASCII 9

;kalau bukan tanda ;flag tanda = 1 ;digit tambah tidak mengurangi CX ;pastikan AH = 0 ;ASCII to number ASCII 0 = 30h ;simpan nilai AX ke stack ; bx = 10 ;(dx ax) = ax x 10

Hendra, MT. & Hartono, M.Kom.

72

Pemrograman Bahasa Rakitan


mov hasil,ax pop ax add hasil,ax bacaBerikutnya: pop cx loop mulaiBaca konversiSigned: cmp [bp],1 jnz selesaiBaca neg word ptr hasil selesaiBaca: mov sp,bp endM ;apakah flag tanda = 1 ;konversi negatif ke komplemen dua ;buang variabel lokal ;ambil nilai AX dari stack ;hasil = hasil + AX

cetakNumerik MACRO nilai local bukanNegatif, prosesDigit, prosesCetak mov ax, nilai or ax,ax jns bukanNegatif push ax mov al,'-' cetakDigit pop ax neg ax bukanNegatif: xor cx, cx prosesDigit: xor dx, dx mov bx,0ah div bx push dx inc cx or ax,ax jnz prosesDigit prosesCetak: pop ax add al,30h cetakDigit

;ax = (dx ax)/bx ;save reminder ;result = 0?

Hendra, MT. & Hartono, M.Kom.

73

Pemrograman Bahasa Rakitan


loop prosesCetak

endM

Latihan
1. Buatlah makro yang mencetak biner, octal, hexa dari suatu byte. 2. Buatlah program yang menerima dua bilangan bulat, lakukan proses penjumlahan dan cetak hasilnya. 3. Buatlah program yang menerima dua bilangan bulat, lakukan proses pengurangan dan cetak hasilnya. 4. Buatlah program yang dapat mencetak luas persegi panjang. 5. Buatlah program yang dapat menghitung fahrenheit dari suhu celcius

Hendra, MT. & Hartono, M.Kom.

74

Pemrograman Bahasa Rakitan

Quiz
1. Buatlah makro-makro berikut ini: Clrscr MACRO gotoXY MACRO x,y 2. Buatlah program yang dapat mencetak daftar ASCII table sebagai berikut : No. ASCII ? ? dst dst No. ASCII ? ? dst dst No. ASCII ? ? dst dst No. ASCII, dst ? ? dst dst

3. Buatlah program yang dapat mencetak daftar basis bilangan sebagai berikut : Dec Oct Hex Bin

4. Buatlah program yang dapat mencetak daftar basis bilangan, dan negasinya dalam bentuk komplemen dua. Dec Oct Hex Bin Dec Oct Hex Bin

5. Buatlah makro yang dapat melakukan penjumlahan dan penguruangan data 32-bit, gunakan ADC longADD MACRO dest, src mov ax, word ptr [dest] add ax, word ptr [src] mov word ptr [dest],ax mov ax, word ptr [dest+2] adc ax, word ptr [src+2] mov word ptr [dest+2],ax endM longSUB MACRO dest, src mov ax, word ptr [dest] sub ax, word ptr [src] mov word ptr [dest],ax mov ax, word ptr [dest+2] sbb ax, word ptr [src+2] mov word ptr [dest+2],ax endM Hendra, MT. & Hartono, M.Kom.

; add with carry

; substract with borrow

75

Pemrograman Bahasa Rakitan

Bab 13, Sub Rutin


Procedure merupakan sub rutin yang dipanggil dengan menggunakan perintah CALL, pada saat perintah CALL terjadi, maka nilai register IP akan didorong ke stack, dan program bercabang ke alamat yang di CALL, dan ketika perintah RET, maka nilai tersebut akan ditarik dari stack ke register IP sehingga program dapat dilanjutkan. Perintah CALL dan RET adalah perintah yang disediakan oleh 8086.

Pembuatan Sub rutin


Pada dasarkan pemrograman 8086 tidak mensyaratkan sintak penulisan khusus untuk suatu procedure, yang perlu ingat adalah agar program dapat kembali ke program pemanggil, maka setiap procedure harus memiliki perintah RET. Tetapi jika anda bekerja dengan Assembler, maka anda diwajibkan menggunakan struktur penulisan sebagai berikut:
nama_procedure instruksi RET name EndP PROC

Sesuatu hal yang perlu anda perhatikan adalah jika didalam procedure anda ada menggunakan perintah PUSH, maka pada titik RET perlu dipastikan bahwa nilai yang ditarik kembali pada saat RET adalah nilai yang didorong pada saat perintah CALL dilakukan. Contoh:
cetakDigit PROC push ax mov ah,0eh int 10h pop ax ret endP barisBaru PROC push ax mov al,0dh call cetakDigit mov al,0ah call cetakDigit pop ax ret endP

Hendra, MT. & Hartono, M.Kom.

76

Pemrograman Bahasa Rakitan

Pemanggilan Sub rutin


Sebagaimana yang telah dijelaskan sebelumnya bahwa pemanggilan sub rutin menggunakan perintah CALL, pada saat perintah CALL dijalankan, maka nilai dari IP akan didorong ke Stack, dan nilai lokasi pemanggilan akan diberikan ke IP sehingga program bercabang ke sub rutin, ketika suatu perintah RET ditemukan, maka akan diambil dari dari stack ke register IP sehingga program bercabang kembali ke perintah setalah CALL.

Hal yang perlu diperhatikan


Jika anda melakukan looping untuk memanggil suatu sub rutin, maka perlu dipastikan bahwa didalam sub rutin tersebut tidak mempengaruhi nilai CX yang merupakan register counter pada program pemanggil, jika anda ragu, sebaiknya sebelum pemanggilan anda perlu menyimpan nilai register CX ke stack, dan menarik kembali nilai register CX setelah pemanggilan. Selain register CX, sebenarnya anda juga perlu memperhatikan perubahan terhadap nilai register lainnya, yang akhirnya akan mempengaruhi hasil proses pada program pemanggil. Contoh:
.model small .stack 100h .data hasil1 dw 0 hasil2 dw 0 .code main PROC call bacaNumerik mov hasil1, ax call barisBaru call bacaNumerik mov hasil2, ax call barisBaru mov ax,hasil1 call cetakNumerik call barisBaru mov ax,hasil2 call cetakNumerik

Hendra, MT. & Hartono, M.Kom.

77

Pemrograman Bahasa Rakitan


call barisBaru mov ah,4ch int 21h

endP

cetakDigit PROC push ax mov ah,0eh int 10h pop ax ret endP barisBaru PROC push ax mov al,0dh call cetakDigit mov al,0ah call cetakDigit pop ax ret endP bacaDigit PROC mulaiBacaDigit: mov ah,0h int 16h cmp jnz xor jmp al,0dh periksaTandaDigit al,al keluarBacaDigit

periksaTandaDigit: cmp al,'-' jnz periksaDigit jmp cetakKeLayar periksaDigit: cmp al,'0' jb mulaiBacaDigit cmp al,'9' jg mulaiBacaDigit cetakKeLayar: call cetakDigit keluarBacaDigit:

Hendra, MT. & Hartono, M.Kom.

78

Pemrograman Bahasa Rakitan


ret ;hasil --> AX

endP

bacaNumerik PROC push bx push cx push dx push bp mov bp,sp push 0 push 0 mov cx,5 mulaiBacaNumerik: push cx call bacaDigit

;variabel signFlag [bp] ;variabel hasil [bp-2]

or al,al jnz periksaTandaNumerik pop cx jmp konversiSignedNumerik periksaTandaNumerik: cmp al,'-' jnz prosesDigitNumerik mov [bp],1 pop cx jmp mulaiBacaNumerik prosesDigitNumerik: push ax xor ah,ah sub al,30h push ax mov ax,[bp-2] mov bx,0ah mul bx mov [bp-2],ax pop ax add [bp-2],ax bacaBerikutNumeriknya: pop ax pop cx or al,al

Hendra, MT. & Hartono, M.Kom.

79

Pemrograman Bahasa Rakitan


loopnz mulaiBacaNumerik konversiSignedNumerik: cmp [bp],1 jnz selesaiBacaNumerik neg word ptr [bp-2] selesaiBacaNumerik: mov ax,[bp-2] ;hasil --> AX mov sp,bp pop pop pop pop ret endP cetakNumerik PROC push bx push cx push dx or ax,ax jns bukanNumerikNegatif push ax mov al,'-' call cetakDigit pop ax neg ax bukanNumerikNegatif: xor cx, cx prosesNumerikAwal: xor dx, dx mov bx,0ah div bx push dx ;nilai --> AX bp dx cx bx

;ax = (dx ax)/bx ;save reminder

inc cx or ax,ax ;result = 0? jnz prosesNumerikAwal prosesCetakNumerik:

Hendra, MT. & Hartono, M.Kom.

80

Pemrograman Bahasa Rakitan


pop ax add al,30h call cetakDigit loop prosesCetakNumerik pop dx pop cx pop bx endP end ret

Latihan
1. Buatlah sebuah sub rutin yang berfungsi membersihkan layar. 2. Buatlah program yang dapat menerima tiga bilangan, dan tampilkan hasil penjumlahan ketiganya .

Hendra, MT. & Hartono, M.Kom.

81

Pemrograman Bahasa Rakitan

Bab 14, Parameter pada Sub Rutin


Didalam pembuatan program, tidak jarang kita perlu mengirim nilai kedalam sub rutin maupun sebaliknya. Komunikasi nilai antara program pemanggil dengan subrutin dapat dilakukan melalui beberapa pendekatan sebagai berikut: 1. Menggunakan register 2. Menggunakan memori 3. Menggunakan stack Dari ketiga jenis pendekatan tersebut diatas, pemakaian register dan memori adalah cukup sederhana dan kita telah melakukannya pada Bab sebelumnya, tetapi pemakaian stack membutuhkan penanganan khusus, walaupun pendekatan ini cenderung lebih rumit, tetapi memiliki manfaat lebih, terutama ketika anda ingin menggunakan procedure yang anda buat dengan bahasa tingkat tinggi lainnya yang umumnya melewatkan nilai ke sub rutin dengan menggunakan stack. Pada bagian ini kita akan menfokuskan pada pembahasan pengiriman parameter lewat stack.

Mengirim parameter lewat Stack


Untuk melewatkan parameter ke sub rutin melalui stack, anda perlu mendorong masingmasing parameter ke stack sebelum proses pemanggilan fungsi dilakukan dengan urutan yang terbalik (parameter terakhir didorong terlebih dahulu). Karena stack bertambah ke bawah, parameter pertama akan ditempatkan pada alamat yang terendah. nama Proc Near Push BP Mov BP, SS Push 0 Push 0 POP BP Ret endP Push Param3 Push Param2 Push Param1 Call nama Kondisi stack ; variabel lokal1 ; variabel lokal2 BP -8 Param3 BP -6 Param2 BP -4 Param1 BP -2 Return Address (hanya IP) BP nilai BP (Push BP) BP +2 Variabel lokal1 BP +4 Variabel lokal2

Hendra, MT. & Hartono, M.Kom.

82

Pemrograman Bahasa Rakitan Pop Param1 Pop Param2 Pop Param3 ; atau add sp + 6

Setelah perintah Call, maka parameter yang didorong ke Stack harus di tarik kembali. GotoXY Proc Push BP Mov BP, SS Mov DX, [BP+4] Mov AH,2 Mov BH,0h Int 10h Ret endP Mov DL, 10 Mov DH, 15 Push DX Call gotoXY Pop DX ;parameter X low byte, Y high byte ;simpan BP ke stack ;BP menunjuk ke nilai BP yang dipush

; X low byte ; Y high byte ; atau add sp, 2

Pengembalian nilai dari sub rutin


Pengembalian nilai dari sub rutin dapat melalui memori, register, maupun Stack.

Latihan
INT 10h / AH = 0 mengatur modus video input: AL = desired video mode. these video modes are supported: 00h - text mode. 40x25. 16 colors. 8 pages. 03h - text mode. 80x25. 16 colors. 8 pages. 13h - graphical mode. 40x25. 256 colors. 320x200 pixels. 1 page. INT 10h / AH = 0Ch - change color for a single pixel. input: AL = pixel color CX = column.

Hendra, MT. & Hartono, M.Kom.

83

Pemrograman Bahasa Rakitan


DX = row.

Sebagaimana yang telah pernah kita bahas sebelumnya bahwa CGA Video memori beradai di segment $B800, maka VGA Video memori berada di segment $A000. Akses langsung kememori memiliki perfomance yanglebih tinggi. Tetapi permasalahan yang dihadapi adalah bagaimana konversi koordinat pixel X,Y ke alamat offset memori, untuk mendapatkan alamat offset dari suatu pixel dapat menggunakan rumus: Offset = X + ( Y * 320 ) Setelah anda mendapatkan alamat offset memori dari pixel tersebut, anda dapat membuat sebuah pixel dengan perintah: mov es:[di], color Dimana ES menunjuk ke segment $A000, dan di menunjuk ke alamat offset dari pixel. Anda dapat juga menggunakan alternatif lain dengan perintah STOSB. Untuk melakukan perkalian 320 dapat dilakukan dengan :
mov shl mov mov shl add mov add ax, ax, di, ax, ax, di, ax, di, Y 8 ax Y 6 ax X ax ; ax = ax * 256 ; ax = ax * 64 ; di = y * (256 + 64) = y * 320 ; di = y * 320 + x

Latihan
1. Buatlah sub rutin initgraph yang berfungsi mengubah dari textmode menjadi grafik mode 2. Buatlah sub rutin putPixel yang berfungsi mengubah warna pada posisi pixel tertentu, warna, dan koordinat dikirim sebagai parameter melalui stack. 3. Buatlah sub rutin putPixelDirect yang berfungsi mengubah warna pada pixel tertentu, warna dan koordinat dikirim sebagai parameter melalui stack, dan pembuatan pixel menggunakan akses langsung ke memori VGA.

Hendra, MT. & Hartono, M.Kom.

84

Pemrograman Bahasa Rakitan

Bab 15, Penanganan I/O


Secara hardware tentu saja mikroprocessor digunakan untuk mengendalikan berbagai peralatan, dan interaksi antara mikroprocessor dengan peralatan tersebut melalui berbagai nomor port yang berbeda. Untuk mengakses port perintah IN dan OUT dapat digunakan.

Membaca dari port


Untuk membaca dari port dapat menggunakan perintah IN dengan sintak penulisan sebagai berikut:
in in in in al, al, ax, ax, immediate byte dx immediate byte dx

perintah tersebut diatas membaca dari port yang ditunjuk oleh immediate byte ataupun register dx ke register al atau dx. Untuk mengakses port dengan nomor diatas 255 digunakan register dx.

Menulis ke port
Untuk menulis ke port dapat menggunakan perintah OUT dengan sintak penulisan sebagai berikut:
out out out out immediate byte, al immediate byte, ax dx, al dx, ax

perintah tersebut diatas menulis ke port yang ditunjuk oleh immediate byte ataupun register dx dari nilai register al atau dx. Contoh: Program Piano (menggunakan FASM)
format MZ entry code_seg:start ; set entry point stack 100h segment data_seg nada dw 106h, 126h, 14ah, 15dh, 188h, 1b8h, 1efh, 200h pesan db "Tekan 12345678 untuk nada, Esc selesai.$" segment code_seg

Hendra, MT. & Hartono, M.Kom.

85

Pemrograman Bahasa Rakitan


start: mov ax, data_seg mov ds, ax mov ah,9h mov dx,pesan int 21h ulang: call readkey cmp al, 1bh jz keluar cmp al, '1' jb ulang cmp al, '8' jg ulang xor ah, ah sub al, '1' shl al, 1 ; ESC = 1b = 27

; al = al * 2

mov bx, nada mov si, ax push word [bx+si] call sound add sp,2 jmp ulang keluar: call nosound mov ax, 4ch int 21h readkey: ;proc mov ah,0 int 16h ret ;endp sound: ;proc push bp mov bp,sp ;parameter -->frek ; exit to dos ; add sp + 1 (recorver stack)

Hendra, MT. & Hartono, M.Kom.

86

Pemrograman Bahasa Rakitan


in al,61h or al,3h out 61h,al mov al,0b6h out 43h,al mov dx,12h mov ax,34deh mov bx,[bp+4] div bx out 42h,al xchg ah,al out 42h,al pop bp ret ;endp nosound: ;proc in al,61h xor al,2h out 61h,al ret ;endp ;baca dari port 61h (8255) ;aktifkan bit 0 timer ; bit 1 speaker

;119318 / frek ;ax = (dx ax) / bx ;ah <--> al

;non aktifkan bit speaker

Traffic lights Emulator

#start=Traffic_Lights.exe# name "traffic" mov ax, all_red out 4, ax

Hendra, MT. & Hartono, M.Kom.

87

Pemrograman Bahasa Rakitan


mov si, offset situation next: mov ax, [si] out 4, ax ; wait 5 seconds (5 million microseconds) mov cx, 4Ch ; 004C4B40h = 5,000,000 mov dx, 4B40h mov ah, 86h int 15h add cmp jb mov jmp si, 2 ; next situation si, sit_end next si, offset situation next dw dw dw dw dw equ FEDC_BA98_7654_3210 0000_0011_0000_1100b 0000_0110_1001_1010b 0000_1000_0110_0001b 0000_1000_0110_0001b 0000_0100_1101_0011b 0000_0010_0100_1001b

; situation s1 s2 s3 s4 sit_end = $ all_red

Thermometer dan Heater Emulator


#start=thermometer.exe# #make_bin# name "thermo" ; set data segment to code segment: mov ax, cs mov ds, ax start: in al, 125 cmp al, 60 jl low

Hendra, MT. & Hartono, M.Kom.

88

Pemrograman Bahasa Rakitan


cmp al, 80 jle ok jg high low: mov al, 1 out 127, al jmp ok high: mov al, 0 out 127, al ok: jmp start

; turn heater "on".

; turn heater "off". ; endless loop.

Stepper Motor

The motor can be half stepped by turning on pair of magnets, followed by a single and so on. The motor can be full stepped by turning on pair of magnets, followed by another pair of magnets and in the end followed by a single magnet and so on. The best way to make full step is to make two half steps. Half step is equal to 11.25 degrees. Full step is equal to 22.5 degrees. The motor can be turned both clock-wise and counter-clock-wise. Contoh:
#start=stepper_motor.exe#

Hendra, MT. & Hartono, M.Kom.

89

Pemrograman Bahasa Rakitan


name "stepper" #make_bin# steps_before_direction_change = 20h ; 32 (decimal) jmp start ; ========= data =============== ; bin data for clock-wise ; half-step rotation: datcw db 0000_0110b db 0000_0100b db 0000_0011b db 0000_0010b ; bin data for counter-clock-wise ; half-step rotation: datccw db 0000_0011b db 0000_0001b db 0000_0110b db 0000_0010b ; bin data for clock-wise ; full-step rotation: datcw_fs db 0000_0001b db 0000_0011b db 0000_0110b db 0000_0000b ; bin data for counter-clock-wise ; full-step rotation: datccw_fs db 0000_0100b db 0000_0110b db 0000_0011b db 0000_0000b start: mov bx, offset datcw ; start from clock-wise half-step. mov si, 0 mov cx, 0 ; step counter next_step: ; motor sets top bit when it's ready to accept new command wait: in al, 7 test al, 10000000b jz wait

Hendra, MT. & Hartono, M.Kom.

90

Pemrograman Bahasa Rakitan


mov al, [bx][si] out 7, al inc si cmp si, 4 jb next_step mov si, 0 inc cx cmp cx, steps_before_direction_change jb next_step mov cx, 0 add bx, 4 ; next bin data cmp bx, offset datccw_fs jbe next_step mov bx, offset datcw ; return to clock-wise half-step. jmp next_step

Robot

Hendra, MT. & Hartono, M.Kom.

91

Pemrograman Bahasa Rakitan


#start=robot.exe# name "robot" #make_bin# #cs = 500# #ds = 500# #ss = 500# #sp = ffff# #ip = 0#

; stack

; this is an example of contoling the robot. ; this code randomly moves the robot, ; and makes it to switch the lamps on and off. ; robot is a mechanical creature and it takes ; some time for it to complete a task. ; status register is used to see if robot is busy or not. ; ; ; ; c:\emu8086\devices\robot.exe uses ports 9, 10 and 11 source code of the robot and other devices is in: c:\emu8086\devices\developer\sources\ robot is programmed in visual basic 6.0

; robot base i/o port: r_port equ 9 ;=================================== eternal_loop: ; wait until robot ; is ready: call wait_robot ; examine the area ; in front of the robot: mov al, 4 out r_port, al call wait_exam ; get result from ; data register: in al, r_port + 1 ; nothing found? cmp al, 0 je cont ; - yes, so continue.

Hendra, MT. & Hartono, M.Kom.

92

Pemrograman Bahasa Rakitan


; wall? cmp al, 255 je cont ; - yes, so continue. ; switched-on lamp? cmp al, 7 jne lamp_off ; - no, so skip. ; - yes, so switch it off, ; and turn: call switch_off_lamp jmp cont ; continue lamp_off: nop ; if gets here, then we have ; switched-off lamp, because ; all other situations checked ; already: call switch_on_lamp cont: call random_turn call wait_robot ; try to step forward: mov al, 1 out r_port, al call wait_robot ; try to step forward again: mov al, 1 out r_port, al jmp eternal_loop ; go again! ;=================================== ; this procedure does not ; return until robot is ready ; to receive next command: wait_robot proc ; check if robot busy: busy: in al, r_port+2 test al, 00000010b jnz busy ; busy, so wait. ret wait_robot endp ;===================================

Hendra, MT. & Hartono, M.Kom.

93

Pemrograman Bahasa Rakitan


; this procedure does not ; return until robot completes ; the examination: wait_exam proc ; check if has new data: busy2: in al, r_port+2 test al, 00000001b jz busy2 ; no new data, so wait. ret wait_exam endp ;=================================== ; switch off the lamp: switch_off_lamp proc mov al, 6 out r_port, al ret switch_off_lamp endp ;=================================== ; switch on the lamp: switch_on_lamp proc mov al, 5 out r_port, al ret switch_on_lamp endp ;=================================== ; generates a random turn using ; system timer: random_turn proc ; get number of clock ; ticks since midnight ; in cx:dx mov ah, 0 int 1ah ; randomize using xor: xor dh, dl xor ch, cl xor ch, dh test ch, 2 jz no_turn test ch, 1

Hendra, MT. & Hartono, M.Kom.

94

Pemrograman Bahasa Rakitan


jnz turn_right ; turn left: mov al, 2 out r_port, al ; exit from procedure: ret turn_right: mov al, 3 out r_port, al no_turn: ret random_turn endp ;===================================

Hendra, MT. & Hartono, M.Kom.

95

Pemrograman Bahasa Rakitan

Daftar Pustaka
Randall Hyde, The Art of Assembly Language, http://homepage.mac.com/randyhyde/webster.cs.ucr.edu/www.artofasm.com/index.html Documentation for 8086 assembler and emulator, http://www.emu8086.com/assembler_tutorial

Hendra, MT. & Hartono, M.Kom.

96

Pemrograman Bahasa Rakitan

Lampiran A, 8086 Menmonic


MNEMONICS 8086/8088/80186/80188/8087/V30/V20
assembly form : examples opcode [type ptr] [register],[address/reg] MOV AX,1234 INC BYTE PTR [BP] MOV AH,AL

machine code : xxxxxxxx[xxxxxxxx]|[mdxxxr/m]|[xxxxxxxx[xxxxxxxx]]|[xxxxxxxx[xxxxxxxx]] opcode 1 / 2 bytes|mdr/m byte| disp 1 / 2 bytes |imm. data 1 / 2 bytes ADDRESS MODES (mdxxxr/m byte) 97 effective address (EA) mdxxxr/m DS:[BX+SI] 00xxx000 DS:[BX+DI] 00xxx001 SS:[BP+SI] 00xxx010 SS:[BP+DI] 00xxx011 DS:[SI] 00xxx100 DS:[DI] 00xxx101 DS:disp16 00xxx110 DS:[BX] 00xxx111 DS:[BX+SI+disp8] 01xxx000 DS:[BX+DI+disp8] 01xxx001 SS:[BP+SI+disp8] 01xxx010 SS:[BP+DI+disp8] 01xxx011 DS:[SI+disp8] 01xxx100 DS:[DI+disp8] 01xxx101 SS:[BP+disp8] 01xxx110 DS:[BX+disp8] 01xxx111 DS:[BX+SI+disp16] 10xxx000 DS:[BX+DI+disp16] 10xxx001 SS:[BP+SI+disp16] 10xxx010 SS:[BP+DI+disp16] 10xxx011 DS:[SI+disp16] 10xxx100 DS:[DI+disp16] 10xxx101 SS:[BP+disp16] 10xxx110 DS:[BX+disp16] 10xxx111 register REGISTERS register 11xxxreg (reg or sr bits) 8bit AL CL DL BL 16bit AX CX DX BX reg 000 001 010 011 segment register 16bit ES CS SS DS sr 00 01 10 11

Hendra, MT. & Hartono, M.Kom.

97

Pemrograman Bahasa Rakitan


AH CH DH BH ADDRESSING MODES mode register immediate direct reg. indirect based indexed based indexed in the instruction in a register in memory example ,BX ,FFH ,[FFH] ,[BX] ,[BX+FFH] ,[SI+FFH] SP BP SI DI 100 101 110 111

register address----operand operand memory address---------------------operand register address----mem. address---operand register address----mem. address-+-operand displacement---------------------^ register address----displacement-+-operand mem. address---------------------^ register address----mem. address-v register address----displacement-+-operand displacement---------------------^ mem. address---operand mem. address---destination port address port address

,[BX+SI+FFH]

string operand I/O port dir. I/O port indir. DATA TRANSFER MOV

,20H ,DX

XCHG PUSH

PUSHA POP

move data register/mem. to/from register immediate to reg./mem. immediate to register mem. to accu (AX/AL) accu to mem. (AX/AL) reg./mem. to segm. reg. segm. reg. to reg./mem. exchange register/memory with register register with accu (AX) push register/memory register segment register immediate push all AX,CX,DX,BX,SP,BP,SI,DI pop

100010dw 1100011w 1011wreg 1010000w 1010001w 10001110 10001100 1000011w 10010reg 11111111 01010reg 000sr110 011010s0 01100000

mdregr/m md000r/m data8/16bit data8/16bit address16bit address16bit md0srr/m md0srr/m mdregr/m md110r/m data8/16bit * *

Hendra, MT. & Hartono, M.Kom.

98

Pemrograman Bahasa Rakitan


register/memory register segment register pop all, except SP, (skipping) DI,SI,BP,xx,BX,DX,CX,AX input from I/O port fixed port variable port in DX output to I/O port fixed port variable port in DX translate byte to AL (AL = [BX + AL]) load EA to register load pointer to DS load pointer to ES load AH with flags (O,D,I,S,Z,A,P,C) store AH into flags (O,D,I,S,Z,A,P,C) push flags pop flags 10001111 01011reg 000sr111 01100001 1110010w 1110110w 1110011w 1110111w 11010111 10001101 11000101 11000100 10011111 10011110 10011100 10011101 port8bit port8bit md000r/m

POPA IN OUT XLAT LEA LDS LES LAHF SAHF PUSHF POPF

mdregr/m mdregr/m mdregr/m

ARITHMETIC ADD add reg./mem. with reg. to either imm. to reg./mem. imm. to accu. (AX/AL) add with carry reg./mem. with reg. to either imm. to reg./mem. imm. to accu. (AX/AL) increment register/memory register ASCII adjust for add decimal adjust for add subtract reg./mem. and reg. to either imm. from reg./mem. imm. from accu. (AX/AL) subtract with borrow reg./mem. and reg. to either imm. from reg./mem. imm. from accu. (AX/AL) decrement register/memory register ASCII adjust for subtract decimal adjust for subtract multiply (unsigned) integer multiply (signed) register/memory immediate ASCII adjust for multiply 000000dw 100000sw 0000010w 000100dw 100000sw 0001010w 1111111w 01000reg 00110111 00100111 001010dw 100000sw 0010110w 000110dw 100000sw 0001110w 1111111w 01001reg 00111111 00101111 1111011w 1111011w 011010s1 11010100 mdregr/m md000r/m data8/16bit data8/16bit mdregr/m md010r/m data8/16bit data8/16bit md000r/m

ADC

INC AAA DAA SUB

mdregr/m md101r/m data8/16bit data8/16bit mdregr/m md011r/m data8/16bit data8/16bit md001r/m

SBB

DEC AAS DAS MUL IMUL AAM

md100r/m md101r/m mdregr/m 00001010 data8/16bit *

Hendra, MT. & Hartono, M.Kom.

99

Pemrograman Bahasa Rakitan


DIV IDIV AAD CBW CWD NEG CMP divide (unsigned) integer divide (signed) ASCII adjust for divide convert byte to word AL in AX convert word to double word (AX in DX : AX) change sign compare reg./mem. and register imm. with reg./mem. imm. with accu. (AX/AL) 1111011w 1111011w 11010101 10011000 10011001 1111011w 001110dw 100000sw 0011110w md110r/m md111r/m 00001010

md011r/m mdregr/m md111r/m data8/16bit data8/16bit

LOGIC AND and reg./mem. with reg. to either imm. to reg./mem. imm. to accu. (AX/AL) or reg./mem. with reg. to either imm. to reg./mem. imm. to accu. (AX/AL) exclusive or reg./mem. with reg. to either imm. to reg./mem. imm. to accu. (AX/AL) invert shift logical left (SAL) register/memory by 1 register/memory by CX register/memory by count shift logical right register/memory by 1 register/memory by CX register/memory by count rotate left register/memory by 1 register/memory by CX register/memory by count rotate right register/memory by 1 register/memory by CX register/memory by count shift arithmetic left (SHL) register/memory by 1 register/memory by CX register/memory by count shift arithmeric right register/memory by 1 register/memory by CX register/memory by count rotate through carry left register/memory by 1 register/memory by CX register/memory by count rotate through carry right 001000dw 100000sw 0010010w 000010dw 100000sw 0000110w 001100dw 100000sw 0011010w 1111011w 1101000w 1101001w 1100000w 1101000w 1101001w 1100000w 1101000w 1101001w 1100000w 1101000w 1101001w 1100000w 1101000w 1101001w 1100000w 1101000w 1101001w 1100000w 1101000w 1101001w 1100000w mdregr/m md100r/m data8/16bit data8/16bit mdregr/m md001r/m data8/16bit data8/16bit mdregr/m md110r/m data8/16bit data8/16bit md010r/m md100r/m md100r/m md100r/m md101r/m md101r/m md101r/m md000r/m md000r/m md000r/m md001r/m md001r/m md001r/m md100r/m md100r/m md100r/m md111r/m md111r/m md111r/m md010r/m md010r/m md010r/m

OR

XOR

NOT SHL

count8bit

SHR

count8bit

ROL

count8bit

ROR

count8bit

SAL

count8bit

SAR

count8bit

RCL

count8bit

RCR

Hendra, MT. & Hartono, M.Kom.

100

Pemrograman Bahasa Rakitan


register/memory by 1 1101000w register/memory by CX 1101001w register/memory by count 1100000w and function to flags (no result) reg./mem. and register 1000010w imm. data and reg./mem. 1111011w imm. data and accu. (AX/AL) 1010100w md011r/m md011r/m md011r/m

count8bit

TEST

mdregr/m md000r/m data8/16bit data8/16bit

STRING MANIPULATION DS:SI = source, ES:DI = destination, CX = rep. count direction flag = direction set = decrement SI/DI clear = increment SI/DI REP REPZ REPNZ REPE REPNE MOVSB MOVSW CMPSB CMPSW SCASB SCASW LODSB LODSW STOSB STOSW INSB INSW OUTSB OUTSW repeat next string oper. repeat for zero (REPE) repeat for not zero (REPNE) repeat for equal (REPZ) repeat for not equal (REPNZ) move byte(s) move word(s) compare byte(s) compare word(s) scan byte(s) scan word(s) load byte(s) to AL load word(s) to AX store byte(s) from AL store word(s) from AX input byte(s) from DX port input word(s) from DX port output byte(s) to DX port output word(s) to DX port 1111001z 11110011 11110010 11110011 11110010 10100100 10100101 10100110 10100111 10101110 10101111 10101100 10101101 10101010 10101011 01101100 01101101 01101110 01101111

* * * *

CONTROL TRANSFER CALL call to subroutine direct within segment indirect within segment direct intersegment indirect intersegment unconditional jump direct within segment direct within segment-short indirect within segment direct intersegment indirect intersegment return from call in segment adding immediate to SP (level) return intersegment adding immediate to SP (level) jump on not below or equal (JA) jump on above or equ. (JNB/JNC) jump on above (JNBE) jump on CX zero jump on not below (JAE/JNC) 11101000 11111111 10011010 11111111 11101001 11101011 11111111 11101010 11111111 11000011 11000010 11001011 11001010 01110111 01110011 01110111 11100011 01110011 disp16bit md010r/m offset:seg32bit md011r/m disp16bit disp8bit md100r/m offset:seg32bit md101r/m data16bit data16bit disp8bit disp8bit disp8bit disp8bit disp8bit

JMP

RET RETF JNBE JAE JA JCXZ JNB

Hendra, MT. & Hartono, M.Kom.

101

Pemrograman Bahasa Rakitan


JBE JB JNC JC JNAE JNA JZ JE JGE JG JNLE JNL JLE JL JNGE JNG JNZ JNE JPE JPO JNP JNS JNO JO JS JP LOOP LOOPNZ LOOPZ LOOPNE LOOPE ENTER LEAVE INT INTO IRET jump on below or equal (JNA) jump on below (JNAE/JC) jump on no carry (JNB/JAE) jump on carry (JB/JNAE) jump on not ab. or equ. (JB/JC) jump on not above (JBE) jump on zero (JE) jump on equal (JZ) jump on greater or equal (JNL) jump on greater (JNLE) jump on not less or equal (JG) jump on not less (JGE) jump on less or equal (JNG) jump on less (JNGE) jump on not great. or equ. (JL) jump on not greater (JLE) jump on not zero (JNE) jump on not equal (JNZ) jump on parity even (JP) jump on parity odd (JNP) jump on not parity (JPO) jump on not sign jump on not overflow jomp on overflow jump on sign jump on parity (JPE) loop CX times loop while not zero (LOOPNE) loop while zero (LOOPE) loop while not equal (LOOPNZ) loop while equal (LOOPZ) enter procedure leave procedure interrupt type specified type 3 interrupt on overflow interrupt return 01110110 01110010 01110011 01110010 01110010 01110110 01110100 01110100 01111101 01111111 01111111 01111101 01111110 01111100 01111100 01111110 01110101 01110101 01111010 01111011 01111011 01111001 01110001 01110000 01111000 01111010 11100010 11100000 11100001 11100000 11100001 11001000 11001001 11001101 11001100 11001110 11001111 disp8bit disp8bit disp8bit disp8bit disp8bit disp8bit disp8bit disp8bit disp8bit disp8bit disp8bit disp8bit disp8bit disp8bit disp8bit disp8bit disp8bit disp8bit disp8bit disp8bit disp8bit disp8bit disp8bit disp8bit disp8bit disp8bit disp8bit disp8bit disp8bit disp8bit disp8bit data16bit level8bit type8bit

* *

PROCESSOR CONTROL CLC STC CMC CLD STD CLI STI ESC HLT LOCK NOP WAIT clear carry set carry complement carry clear direction set direction clear interrupt set interrupt escape (to external device) halt bus lock prefix (no external bus no operation wait till test pin is low 11111000 11111001 11110101 11111100 11111101 11111010 11111011 11011xxx mdxxxr/m 11110100 request allow. on next instr.) 11110000 10010000 10011011

Hendra, MT. & Hartono, M.Kom.

102

Pemrograman Bahasa Rakitan


SEGMENT CONTROL ES: CS: SS: DS: segment segment segment segment override override override override prefix prefix prefix prefix ES CS SS DS 001sr110 00100110 00101110 00110110 00111110

SPECIAL BITS d w s z x direction from/to 0 from register 1 to register word/byte 0 8bit data/reg. instruction 1 16bit data/reg. instruction sign extended 8bit or 16bit, w = 1 0 16bit data 1 8bit sign extended to 16bit uses for string primitives for comparison with ZF flag (zero) is don't care, uses with external device (8087)

SEGMENT REGISTERS sr 00 01 10 11 POSTBYTE md 00 01 10 11 r/m segment register ES CS SS DS (mdregr/m) mode if r/m = 110 then EA = disp16bit, else disp = 0 (no disp) disp is 8bit, sign extended to 16bit disp is 16bit r/m is a reg field disp follows 2nd byte of instruction (before data if required) register/memory 000 EA = (BX)+(SI)+disp / AX / AL 001 EA = (BX)+(DI)+disp / CX / CL 010 EA = (BP)+(SI)+disp / DX / DL 011 EA = (BP)+(DI)+disp / BX / BL 100 EA = (SI)+disp / SP / AH 101 EA = (DI)+disp / BP / CH 110 EA = (BP)+disp / SI / DH when md = 00, EA = disp16bit 111 EA = (BX)+disp / DI / BH disp follows 2nd byte of instruction (before data if required) register 8/16bits 000 AL / AX 001 CL / CX 010 DL / DX 011 BL / BX 100 AH / SP 101 CH / BP

reg

Hendra, MT. & Hartono, M.Kom.

103

Pemrograman Bahasa Rakitan


110 DH / SI 111 BH / DI * is extended opcodes, not available in 8086/8088 only on V20/V30/80188/80186 and upper procedure protocol : ENTER data,level

: data is number of bytes to reserve on the stack level is nesting depth 1 = top, 0 = no nesting push BP on the stack, move SP in BP, look at level, if level is not zero then push level-1 words on the stack from old BP value address down, then push BP if level > 0. Finally subtract data from SP:

SP stack BP stack SP after->| | | | |------| | | : undef } data value | | |------| | | (SP/2)->|BP aft|>-when level > 0 | | |------| |------| :BP xxx:<-------------------<:BP xxx } level value -1 |------| |------| (SP/1)-BP after->|BP bef| BP before->|BP xxx| |------| |------| high mem. SP before->| | | | |------| | | low mem. SP/BP before is value before ENTER opcode SP/BP after is value after ENTER opcode SP/1 is SP after when level and data is 0 SP/2 is SP after when data is 0 and level > 0 BP xxx is stack pointers from prev. procedure(s) LEAVE : move BP to SP, pop BP ; MOV SP,BP POP BP

Hendra, MT. & Hartono, M.Kom.

104

Pemrograman Bahasa Rakitan

Lampiran B, TABEL ASCII

Hendra, MT. & Hartono, M.Kom.

105

Pemrograman Bahasa Rakitan

LAMPIRAN C, BINARY KE HEXADESIMAL

Hendra, MT. & Hartono, M.Kom.

106

Pemrograman Bahasa Rakitan

Lampiran D, Menghubungkan ASM dengan Pascal


1. Gunakan model memory large, PASCAL 2. Deklarasikan fungsi-fungsi yang akan diekspor sebagai public 3. Jika anda melakukan perubahan terhadap nilai register BP, SP, SS dan DS registers. Maka anda perlu mengembalikan nilainya. 4. Assember file tersebut menjadi OBJ 5. Pada pascal deklarasi masing-masing procedure/function yang akan dimport sebagai far; external. 6. Gunakan compiler direktif {$L nama_obj.obj} 7. Pengembalian nilai pada function dilakukan pada AL (byte), AX (Integer/Word) Contoh :
Pascrt.Asm .MODEL large,PASCAL public public public public public .CODE clrscr PROC FAR mov ah,07h mov al,00h mov bh,07h mov ch,00h mov cl,00h mov dh,19h mov dl,50h int 10h ret ENDP PROC FAR x:BYTE, y:BYTE mov dl,x mov dh,y mov ah,02h mov bh,00h int 10h ret ENDP PROC FAR clrscr gotoxy readkey sound nosound

clrscr gotoxy

gotoxy readkey

Hendra, MT. & Hartono, M.Kom.

107

Pemrograman Bahasa Rakitan


mov ah,00h int 16h ret ENDP ;return value in AL

readkey sound

sound nosound

PROC FAR frek:WORD in al,61h or al,3h out 61h,al mov al,0b6h out 43h,al mov dx,12h mov ax,34deh mov bx,frek div bx out 42h,al xchg ah,al out 42h,al ret ENDP PROC FAR in al,61h xor al,2h out 61h,al ret ENDP END

nosound

{Piano.Pas} program piano; procedure clrscr; procedure gotoxy(x,y:byte); function readkey : byte; procedure sound(frek : word); procedure nosound; {$L PASCRT.OBJ} var key : byte;

far; far; far; far; far;

external; external; external; external; external;

const nada : array [0..7] of word = ($106,$126,$14a,$15d,$188,$1b8,$1ef, $200); begin clrscr; gotoxy(5,5); writeln('Program Piano'); repeat

Hendra, MT. & Hartono, M.Kom.

108

Pemrograman Bahasa Rakitan


key := readkey; if (key >= $31) and (key <= $38) then sound (nada[key-$31]); until key = $0d; nosound; end.

Hendra, MT. & Hartono, M.Kom.

109

Pemrograman Bahasa Rakitan

Lampiran E, Build-in ASM pada Turbo Pascal


Pada prinsipnya programmer dapat langsung mengetik kode Assembly pada program Turbo Pascal 6.0 keatas dengan blok asm...end; Contoh :
const textattr : byte = $7; procedure clrscr; assembler; asm mov ah,7h mov al,0h mov bh,textattr mov ch,0h mov cl,0h mov dh,19h mov dl,50h int 10h end; procedure gotoxy(x,y:byte); assembler; asm mov dl,x mov dh,y mov ah,2h mov bh,0h int 10h end; function readkey : byte; assembler; asm mov ah,0h int 16h ;return value in AL end; procedure sound(frek : word); assembler; asm in al,61h or al,3h out 61h,al mov al,0b6h out 43h,al mov dx,12h mov ax,34deh mov bx,[frek]; div bx out 42h,al

Hendra, MT. & Hartono, M.Kom.

110

Pemrograman Bahasa Rakitan


xchg ah,al out 42h,al end; procedure nosound; assembler; asm in al,61h xor al,2h out 61h,al end; var key : byte; const nada : array [0..7] of word = ($106,$126,$14a,$15d,$188,$1b8,$1ef, $200); begin clrscr; gotoxy(5,5); writeln('Program Piano'); repeat key := readkey; if (key >= $31) and (key <= $38) then sound (nada[key-$31]); until key = $0d; nosound; end.

Hendra, MT. & Hartono, M.Kom.

111

Pemrograman Bahasa Rakitan

Lampiran F, Menghubungkan Turbo C/C++ dengan Assembly


.model small, C .286 .code PUBLIC PUBLIC PUBLIC PUBLIC PUBLIC PUBLIC initgraph closegraph putpixel putpixelc putpixel_direct getch NEAR ah,0h al,13h 10h

initgraph proc mov mov int ret initgraph ENDP

closegraph proc NEAR mov ah,0h mov al,3h int 10h ret closegraph ENDP putpixel proc NEAR push bp mov bp,sp mov ah,0ch mov cx,[bp+4] ; x mov dx,[bp+6] ; y mov al,[bp+8] ; c int 10h pop bp ret putpixel ENDP putpixelc proc mov mov mov mov int ret putpixelc ENDP NEAR x:WORD,y:WORD, c:BYTE ah,0ch cx,[x] dx,[y] al,[c] 10h

Hendra, MT. & Hartono, M.Kom.

112

Pemrograman Bahasa Rakitan


putpixel_direct proc NEAR x:WORD,y:WORD, c:BYTE push di push es mov mov mov shl mov mov shl add add mov mov ax,0a000h es,ax ax,[y] ax,8h di,ax ax,[y] ax,6h di,ax di,[x] al,[c] es:[di],al

pop es pop di ret putpixel_direct ENDP getch proc NEAR xor ax,ax mov ah,0 int 16h ret getch ENDP END #include <stdlib.h> extern extern extern extern extern extern "C" "C" "C" "C" "C" "C" void initgraph(); closegraph(); char kbhit(); putpixel(int, int, char); putpixelc(int, int, char); putpixel_direct(int, int, char);

void bar_direct(int x1, int y1, int x2, int y2, char c) { int tempx, tempy; for (tempx=x1;tempx<=x2;tempx++) for(tempy=y1;tempy<=y2;tempy++) putpixel_direct(tempx,tempy,c); } void bar(int x1, int y1, int x2, int y2, char c) { int tempx, tempy;

Hendra, MT. & Hartono, M.Kom.

113

Pemrograman Bahasa Rakitan


for (tempx=x1;tempx<=x2;tempx++) for(tempy=y1;tempy<=y2;tempy++) putpixel(tempx,tempy,c); } int main() { int x1,x2,y1,y2; char c; initgraph(); do { x1 = random(300); y1 = random(200); x2 = x1 + random(320-x1); y2 = y1 + random(220-y1); c = 1 + random(16); bar_direct(x1,y1,x2,y2,c); } while (!kbhit()); closegraph(); return 0; } TASM -mx graphics.asm TCC -1 -I..\include -L..\lib tc_asm_e.cpp graphics.obj

Hendra, MT. & Hartono, M.Kom.

114

Pemrograman Bahasa Rakitan

Lampiran F, Build-in ASM pada Turbo C


Return value : Char Short int Int Long int AL AX AX MSB in DX, LSB in AX

Near pointer (offset AX only) Far pointer (segment:offset) DX:AX

#include #include #include #include

<graphics.h> <stdlib.h> <conio.h> <dos.h>

int main() { int x1,x2,y1,y2; char c; int gd,gm; detectgraph(&gd,&gm); gd = CGA; gm = CGAC0; initgraph(&gd,&gm,"egavga.bgi"); do { x1 = random(300); y1 = random(200); x2 = x1 + random(320-x1); y2 = y1 + random(220-y1); c = 1 + random(16); setfillstyle(1,c); bar(x1,y1,x2,y2); } while (!kbhit()); closegraph(); return 0; } #include <stdlib.h> void initgraph() { asm { mov ah,0h mov al,13h int 10h }

Hendra, MT. & Hartono, M.Kom.

115

Pemrograman Bahasa Rakitan


} void closegraph() { asm { mov ah,0h mov al,03h int 10h } } char kbhit() { asm { xor al,al mov ah,1h int 16h; } } void putpixel_direct(int x, int y, char c) { asm { push es mov ax,0a000h push ax pop es mov ax,y shl ax,8h mov di,ax mov ax,y shl ax,6h add di,ax add di,x mov al,c mov es:[di],al pop es } } void putpixel(int x, int y, char c) { asm { mov ah,0ch mov al,[c]; mov cx,[x]; mov dx,[y]; int 10h } }

Hendra, MT. & Hartono, M.Kom.

116

Pemrograman Bahasa Rakitan


void bar_direct(int x1, int y1, int x2, int y2, char c) { int tempx, tempy; for (tempx=x1;tempx<=x2;tempx++) for(tempy=y1;tempy<=y2;tempy++) putpixel_direct(tempx,tempy,c); } void bar(int x1, int y1, int x2, int y2, char c) { int tempx, tempy; for (tempx=x1;tempx<=x2;tempx++) for(tempy=y1;tempy<=y2;tempy++) putpixel(tempx,tempy,c); } int main() { int x1,x2,y1,y2; char c; initgraph(); do { x1 = random(300); y1 = random(200); x2 = x1 + random(320-x1); y2 = y1 + random(220-y1); c = 1 + random(16); bar_direct(x1,y1,x2,y2,c); } while (!kbhit()); closegraph(); return 0; }

Hendra, MT. & Hartono, M.Kom.

117

You might also like