Professional Documents
Culture Documents
DIKTAT KULIAH
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 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.
Pemrograman Bahasa Rakitan E:\> CD \920403024\ASM E:\920403024\ASM> 3. Ketikan perintah Debug.exe untuk mengaktifkan program Debug E:\920403024\ASM>Debug.exe
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 (.).
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
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.
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
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...............
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.
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.
10
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
INT
11001101
type8bit
11
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.
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
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
13
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
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.
15
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.
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
;Hello World
;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
18
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.
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.
20
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
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
23
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.
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.
26
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
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
Pemrograman Bahasa Rakitan 'dan byte 00 ke memori DS:1235 mov byte [1234],10 'akan mengisi byte 10 ke memori DS:1234
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]
29
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.
Secara default untuk register bx mengacu kepada DS, dan register bp mengacu kepada SS.
30
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:
31
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]
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
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
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.
34
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.
35
JB , JNAE, JC
CF = 0
JNAE, JB
JBE , JNA
CF = 1 or ZF = 1
JNBE, JA
ZF = 1 JNLE, JG or SF <> OF
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
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.
38
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
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.
39
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
40
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
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
42
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:
; 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
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
44
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
46
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
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.
48
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:
49
Pemrograman Bahasa Rakitan CF. Kemudian dilakukan update nilai DI dan 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]
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
main endp pesan db "hello world!$" end utama .data pesan db "hello world!$" end
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.
54
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
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
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.
56
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..
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.
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.
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.
58
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.
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.
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.
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.
60
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.
61
;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
62
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
63
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.
64
; 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
65
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
66
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
67
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.
68
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
69
mov
70
;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
71
;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
72
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
73
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
74
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.
75
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
76
77
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:
78
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
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
79
80
Latihan
1. Buatlah sebuah sub rutin yang berfungsi membersihkan layar. 2. Buatlah program yang dapat menerima tiga bilangan, dan tampilkan hasil penjumlahan ketiganya .
81
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
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.
83
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.
84
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
85
; 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)
86
87
88
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#
89
90
Robot
91
; 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.
92
93
94
95
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
96
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
97
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 * *
98
POPA IN OUT XLAT LEA LDS LES LAHF SAHF PUSHF POPF
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
SBB
99
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
100
count8bit
TEST
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
101
* *
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
102
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
103
: 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
104
105
106
clrscr gotoxy
gotoxy readkey
107
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;
const nada : array [0..7] of word = ($106,$126,$14a,$15d,$188,$1b8,$1ef, $200); begin clrscr; gotoxy(5,5); writeln('Program Piano'); repeat
108
109
110
111
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
112
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;
113
114
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 }
115
116
117