Membuat bootstrap loader untuk UFD

Pada beberapa mata kuliah seperti sistem operasi dan sistem berkas, dosen mungkin harus mendemokan beberapa komponen low-level yang tidak tersedia pada sistem operasi modern.  Seperti yang diketahui, seluruh sistem operasi modern zaman sekarang beroperasi pada CPU protected mode.  Hal ini berarti hanya kode program saja yang berada di ring 0, sementara kode program yang dibuat user tidak akan mendapatkan akses ring 0 (kecuali bila diizinkan oleh sistem operasi).  Beberapa instruksi assembly seperti IN, OUT, dan beberapa INT umumnya dibatasi oleh sistem operasi.  Sebagai contoh, Windows akan menolak instruksi IN/OUT pada program user mode tetapi mengizinkannya pada driver.  Sementara di Linux, IN/OUT diperbolehkan bila sebelumnya terdapat pemanggilan ioperm() dan program di-akses dengan hak akses superuser.

Bagaimana bila seseorang ingin tetap menjalankan programnya di CPU real-mode?  Ia harus membuat sistem operasi sendiri!  Atau untuk sebuah eksperimen sederhana, ia dapat membuat sebuah bootstrap loader yang akan menjalankan sebuah program real mode begitu komputer dinyalakan!  Dan untuk eksperimen seperti ini, media UFD (USB Flash Drive) adalah pilihan yang tepat.  Kebanyakan BIOS di motherboard zaman sekarang sudah mendukung emulasi disk untuk UFD, sehingga mendukung proses boot dari UFD.

Ini adalah percobaan yang saya lakukan dengan menggunakan sebuah UFD berukuran 4 GB yang menggunakan file system FAT32.  UFD tersebut hanya mengandung sebuah partisi.  Saya menyalin boot sector dari partisi pertama.  Struktur boot sector untuk FAT32 dapat dilihat di http://en.wikipedia.org/wiki/FAT32.  Berikut ini kode program assembly (dalam NASM) yang membentuk boot sector di UFD saya beserta dengan bootstrap loader buatan sendiri:

[BITS 16]
[ORG 0x7C00]

	jmp	mulai
	nop

	; ------------------------------------------------------
	; Informasi Boot Sector
	; ------------------------------------------------------

	db 'SOS-JCH '					; OEM name
	db 00, 0x2					; Bytes per sector
	db 0x8						; Sector per cluster
	db 0x20, 00					; Reserved sector count
	db 0x2						; Number of FAT
	db 00, 00, 00,00
	db 0xF8						; Media descriptor (F8 = Fixed disk)
	db 00, 00
	db 0x3E, 00					; Sectors per track
	db 0x7C, 00					; Number of heads
	db 00, 00, 00, 00				; Count of hidden sectors
	db 0xA2, 0xA7, 0x77, 00				; Total sectors
	db 0xDB, 0x1D, 00, 00				; Sectors per FAT
	db 00, 00					; Mirroring flags
	db 00, 00					; Version
	db 0x02, 00, 00, 00				; Cluster number of root directory start
	db 0x01, 00					; Sector number of FS Information Sector
	db 0x06, 00					; First sector number of a copy of three FAT32 boot sectors
	db 00, 00, 00, 00
	db 00, 00, 00, 00
	db 00, 00, 00, 00
	db 00, 00
	db 0x29						; Extended boot signature
	db 0xA5, 0x82, 0x1D, 0x86			; Volume ID
	db 'Latihan    '				; Volume Label
	db 'FAT32   '					; File system type

	; ------------------------------------------------------
	; Starting point
	; ------------------------------------------------------
mulai:

	; ------------------------------------------------------
	; Inisialisasi
    	; ------------------------------------------------------
	cli
	xor ax, ax
	mov ss, ax
	mov sp, 0x7C00
	mov ds, ax
	mov es, ax
	sti

	; ------------------------------------------------------
	; Menyalin FAT dan menyimpannya ke lokasi offset 0x7E00
	; ------------------------------------------------------ 

	mov word [ds:dap_jumlah_sector], 1
	mov word [ds:dap_dest_segment], ds
 	mov word [ds:dap_dest_offset], 0x7E00
	mov dword [ds:dap_lba_lo], 94 

	call bacasector

	mov eax, [0x7E08]
	mov [fat_next_cluster], eax

	; ------------------------------------------------------
	; Menyalin RootDirectoryEntry ke lokasi offset 0x8000
	; ------------------------------------------------------
	mov word [ds:dap_jumlah_sector], 8
 	mov word [ds:dap_dest_offset], 0x8000
	mov dword [ds:dap_lba_lo], 0x3C14
	call bacasector

	; ------------------------------------------------------
	; Mencari File Dengan Nama KERNEL.BIN
	; ------------------------------------------------------
proses_cluster_berikutnya:

	mov si, 0x8000

pencarian_file_kernel:

	push si
	lea di,	[nama_file_kernel]
	cld
	mov cx, 11
	repe cmpsb
	jz file_kernel_ditemukan

	;
	; File kernel tidak ditemukan pada entry ini.
  	; Lanjut ke entry direktori berikutnya.
	;

	pop si
	add si, 32
	cmp si, 0x9000
	jbe pencarian_file_kernel

	;
	; File kernel tidak ditemukan di cluster ini
	; Periksa apakah masih ada cluster berikutnya.
	;

	mov eax, [fat_next_cluster]
	and eax, 0x0ffffff0
	cmp eax, 0x0ffffff0
	jz hang

	mov di, 0x8000
	call bacacluster
	call bacafat32

	jmp proses_cluster_berikutnya

file_kernel_ditemukan:

	;------------------------------------------------------------
	; Baca File Kernel dan Salin Di Lokasi Memori 0x8000
	;------------------------------------------------------------
	pop si
	mov ax, word [si+0x14]
	shl eax, 16
	mov ax, [si+0x1A]
	mov [fat_next_cluster], eax
	mov di, 0x8000

baca_cluster_kernel_berikutnya:
	call bacacluster
	call bacafat32
	mov eax, [fat_next_cluster]
	and eax, 0x0ffffff0
	cmp eax, 0x0ffffff0
	jz start_kernel

	add di, 0x1000
	mov eax, [fat_next_cluster]
	jmp baca_cluster_kernel_berikutnya

	;------------------------------------------------------------
	; Mulai eksekusi kernel
	;------------------------------------------------------------
start_kernel:	
	jmp 0x8000

hang:
	jmp hang

bacafat32:
	;
	; Baca sebuah sektor FAT32 ke lokasi 0x7E00
	; Perhitungan berdasarkan nilai memori [fat_next_cluster]
	;

	; Mengisi fat_next_cluster dengan nilai
	; entry fat berikutnya
	; Rumus: sector = 62 + 32 + fat_next_cluster / 128
	;	 offset = (fat_next_cluster % 128 ) * 4

	xor eax, eax
	xor edx, edx
	mov ax, [fat_next_cluster]
	mov dx, [fat_next_cluster+2]
	mov cx, 128
	div cx 

	push dx  	; remainder, untuk offset nanti

	add eax, 94;
	mov word [ds:dap_jumlah_sector], 1
	mov word [ds:dap_dest_offset], 0x7E00
	mov dword [ds:dap_lba_hi], 0
	mov dword [ds:dap_lba_lo], eax
	call bacasector

	pop dx
	shl dx, 2
	add edx, 0x7E00
	mov ecx, [edx]
	mov [fat_next_cluster], ecx

	ret

bacacluster:
	;
	; Baca cluster data berikutnya.
	; eax = nomor cluster
	;  di = offset tujuan
	; Rumus menghitung sector dari cluster:
	;  s = 62 + 15318 + ((c-2)*8)
	;
	dec eax
	dec eax
	mov ecx, 8
	mul ecx
	xor ecx, ecx
	add eax, 15380
	adc edx, ecx
	mov dword [ds:dap_lba_hi], edx
	mov dword [ds:dap_lba_lo], eax
	mov word [ds:dap_jumlah_sector], 8
 	mov word [ds:dap_dest_offset], di
	call bacasector
	ret

bacasector:
	mov ah, 0x42
	mov dl, 0x80
	mov si, dap
	int 0x13
	ret

dap			db	0x10, 0x00
dap_jumlah_sector	dw	0x0001
dap_dest_offset		dw	0x0000
dap_dest_segment	dw	0x007C
dap_lba_lo		dd	0x00000000
dap_lba_hi		dd	0x00000000

pesan_salah_fat32	db	'Kernel tidak ditemukan.',0
nama_file_kernel	db	'KERNEL  BIN'
fat_next_cluster	dd	0x00000000

times 510-($-$$) db 0
dw 0xAA55

Directive [BITS 16] memberi tahu NASM bahwa output dari assembly ini adalah kode program real mode 16-bit.  Pada saat BIOS selesai menyalin boot sector, ia akan memindahkan IP pada 0x7C00 sehingga instruksi yang akan dikerjakan adalah 0x7C00.  Itu sebabnya terdapat directive [ORG 0x7C00].

Assembly di atas jauh dari sederhana, sehingga masih banyak perbaikan yang dapat dilakukan.  Salah satunya adalah saya menganggap 1 cluster terdiri atas 8 sector dan 1 sector terdiri atas 512 bytes.  Hal ini berlaku pada UFD saya, tetapi mungkin berbeda pada UFD yang di-format secara berbeda.  Selain itu, saya menganggap sector yang menampung informasi Root Directory dimulai dari lokasi sector ke 15.318.  Saya juga menganggap jarak dari MBR ke boot sector adalah 62 sector.  Kode assembly yang lebih baik akan menyertakan proses perhitungan (berdasarkan informasi field di boot sector) sehingga bootstrap loader menjadi fleksibel.

Kode assembly yang ada pada dasarnya akan memeriksa linked list di FAT32 dan membaca seluruh cluster yang berisi informasi Root Directory.  Bootstrap loader akan mencari file bernama KERNEL.BIN.  Bila file ini ketemu, isi dari file tersebut akan disalin ke lokasi memori 0x8000, dan eksekusi akan dilanjutkan pada lokasi memori tersebut.

Kode assembly di atas dapat diproses menjadi sebuah boot sector dengan menggunakan NASM:

nasm -o boot.bin boot.asm

Output dari perintah di atas adalah sebuah file berukuran 512 bytes dan diakhir dengan 0x55AA.  Semuanya memenuhi persyaratan sebuah boot sector.  Langkah berikutnya adalah men-copy file tersebut ke boot sector partisi pertama di UFD.  Hal ini dapat dilakukan dengan perintah dd di Linux:

$ sudo dd if=boot.bin of=/dev/sdb1 bs=512 count=1

Sebelum mulai restart komputer dan mengatur prioritas boot device di BIOS, pastikan terlebih dahulu bahwa boot flag pada partisi /dev/sdb1 telah di-set menjadi true.  Untuk mengatur flag tersebut, seseorang bisa menggunakan perintah fdisk di Linux.

Sekarang, pada saat ingin mencoba kode program real mode, seorang programmer assembly hanya perlu menyimpan program tersebut dengan nama KERNEL.BIN.  Setelah itu, copy file KERNEL.BIN ke root directory flash disk.  Kini, setiap kali komputer di-boot melalui flash disk, file KERNEL.BIN akan dikerjakan.

Perlu diingat bahwa program real-mode memiliki memori yang terbatas.  Akses memori hanya dibatasi pada range 1 MB (bila gate A20 aktif, menjadi 1.114.096 bytes).  Area memori ini sudah termasuk yang dipakai untuk Interrupt Descriptor Table (IDT), buffer I/O, dsb sehingga yang tersedia bagi program lebih sedikit lagi.   Untuk memakai memori lebih dari 1 MB, programmer harus beralih ke protected mode (itu sebabnya semua sistem operasi modern bekerja pada protected mode).

Menghindari Google Dengan robots.txt

Google sangat bermanfaat bagi banyak orang, memudahkan orang untuk menemukan situs yang dibutuhkannya secara cepat.  Akan tetapi, ada kalanya Google bisa jadi berbahaya, terutama bagi pemilik situs.  Setiap harinya, program komputer yang disebut Web crawler atau Web robots akan mengunjungi halaman-halaman yang ada di web.  Program pintar tersebut akan membaca isi HTML, mencari hyperlink dalam HTML, lalu mengunjungi setiap HTML yang ada dalam hyperlink, dan seterusnya..  Halaman-halaman yang telah dibacanya akan disimpan dalam bentuk index.  Dan index inilah yang  dipakai bila seseorang melakukan pencarian nantinya.

Bagaimana bila ada halaman tertentu yang tidak penting tetapi ikut ter-index?  Atau ada halaman yang bisa di-akses secara publik, tetapi tidak ingin dipublikasikan di Google?

Salah satu cara yang dapat dilakukan adalah dengan membuat file robots.txt di folder root dari situs.  File ini harus dapat diakses dengan link seperti http://www.domain.com/robots.txt

Sebagai contoh, isi file www.facebook.com/robots.txt adalah:

# Notice: if you would like to crawl Facebook you can
# contact us here: http://www.facebook.com/apps/site_scraping_tos.php
# to apply for white listing. Our general terms are available
# at http://www.facebook.com/apps/site_scraping_tos_terms.php

User-agent: baiduspider
Disallow: /ac.php
Disallow: /ae.php
Disallow: /album.php
Disallow: /ap.php
Disallow: /feeds/
Disallow: /l.php
Disallow: /o.php
Disallow: /p.php
Disallow: /photo.php
Disallow: /photo_comments.php
Disallow: /photo_search.php
Disallow: /photos.php

User-agent: Googlebot
Disallow: /ac.php
Disallow: /ae.php
Disallow: /album.php
Disallow: /ap.php
Disallow: /feeds/
Disallow: /l.php
Disallow: /o.php
Disallow: /p.php
Disallow: /photo.php
Disallow: /photo_comments.php
Disallow: /photo_search.php
Disallow: /photos.php

User-agent: msnbot
Disallow: /ac.php
Disallow: /ae.php
Disallow: /album.php
Disallow: /ap.php
Disallow: /feeds/
Disallow: /l.php
Disallow: /o.php
Disallow: /p.php
Disallow: /photo.php
Disallow: /photo_comments.php
Disallow: /photo_search.php
Disallow: /photos.php

... (bagian selanjutnya tidak ditampilkan)

Dengan demikian, setiap kali web crawler dari Baidu, Google, dan MSN (serta lainnya yang tidak ditampilkan di atas) mengunjungi situs, mereka tidak akan mengakses bagian dalam Disallow seperti /photo.php, /album.php, /feeds dan sebagainya.

Untuk menghasilkan file robots.txt secara otomatis, seseorang dapat memakai generator seperti yang ada di http://www.mcanerin.com/EN/search-engine/robots-txt.asp

Satu hal yang harus diperhatikan adalah robots.txt hanya berfungsi sebagai rekomendasi bagi web crawler saja!!  Ada beberapa web crawler yang tidak mengindahkan isi robots.txt, terutama web crawler yang memiliki ‘niat buruk’.  Crawler seperti ini biasanya disebut bad bots.  Bahkan ada bad bots yang dirancang khusus untuk mencari lokasi yang tertuang dalam robots.txt (yang seharusnya tidak boleh dikunjungi). Jadi, robots.txt tidak untuk melindungi halaman yang sensitif.  Bila ada halaman yang sangat sensitif yang tidak ingin dilihat oleh orang lain, cara yang paling jitu tetap dengan authentication seperti username dan password, sehingga bad bots yang tidak mengetahui username & password tidak dapat melihat konten tersebut.

URL Rewriting Di Apache HTTP Server

Seorang programmer PHP membuat file latihan.php di folder web-nya.  Untuk mengakses file tersebut, pengguna harus mengetikkan URL seperti http://www.domain.com/latihan.php. Dengan demikian, URL selalu berisi informasi yang dipetakan terhadap file fisik.  Hal ini tidak berlaku di JEE: user mengakses sebuah Servlet bukan berdasarkan nama class, tetapi berdasarkan nilai element urlPatterns di WebServlet annotation.

Seandainya programmer PHP tersebut membuat file post.php yang diakses seperti ini:

http://www.domain.com/post.php?tahun=2012&bulan=11&tanggal=01

Kemudian ia merasa bahwa URL tersebut terlalu panjang, alangkah sederhananya bila URL tersebut diakses seperti:

http://www.domain.com/2012/10/01

Apa yang harus ia lakukan tanpa membuat file baru?  Proses yang harus ia lakukan dikenal sebagai URL rewriting.  Bila ia memakai Apache HTTP Server, ia dapat menggunakan Apache mod_rewrite yang menyediakan fungsi tersebut.

Sebelum menggunakan Apache mod_rewrite, pastikan terlebih dahulu modul tersebut sudah di-load, dengan memeriksa isi file konfigurasi Apache.  Sebagai informasi, nama file konfigurasi Apache HTTP Server adalah httpd.conf (pada server Linux, biasanya terdapat di direktori /etc).  Pastikan baris berikut tidak di-comment (tidak diawali tanda #):

LoadModule rewrite_module modules/mod_rewrite.so

Bila si programmer tidak memiliki akses pada folder sensitif, ia dapat membuat sebuah file PHP dengan isi seperti berikut:

<?php
phpinfo();
?>

Setelah menjalankan PHP tersebut di-browser, sang programmer dapat memeriksa bagian apache2handler di baris Loaded Modules.  Bila terdapat tulisan mod_rewrite, maka ia dapat menggunakan fitur URL Rewriting dari Apache HTTP Server.

Langkah berikutnya yang harus dilakukan adalah menambahkan directive untuk keperluan mod_rewrite.  Hampir semua directive dapat diletakkan di file konfigurasi httpd.conf, akan tetapi bila si programmer tidak memiliki akses untuk mengubah httpd.conf, ia terpaksa harus meletakkannya pada file .htaccess. Ada beberapa directive yang tidak dapat diletakkan di .htaccess, misalnya RewriteLog dan RewriteLogLevel yang memungkinkan log yang berisi informasi mengenasi proses URL rewriting yang terjadi.

Selain itu, pastikan AllowOverride bernilai All pada directive Directory yang berisi lokasi direktori fisik.  Bila AllowOverride bernilai None, maka file .htaccess akan diabaikan oleh Apache HTTP Server.

Langkah terakhir, si programmer membuat file .htaccess di direktori utama, yang isinya seperti berikut ini:

RewriteEngine On
RewriteRule ^([0-9]{4})/([0-9]{2})/([0-9]{2})$ /post.php?tahun=$1&bulan=$2&tanggal=$3

Directive RewriteRule di atas mengandung dua bagian, yaitu bagian Pattern dan bagian Substitution.

Bagian Pattern berisi regular expression yang akan dicocokkan dengan URL yang diberikan oleh pengguna.  Pada regex, [0-9]{4}/ menunjukkan bahwa wajib terdapat empat digit angka (contoh pola yang memenuhi: 1994/, 2004/; contoh pola yang salah: abcd/, 19/).  Lalu [0-9]{2}/ menunjukkan bahwa wajib terdapat dua digit angka (contoh pola yang memenuhi: 10/, 11/, dan sebagainya).  Dengan demikian, secara keseluruhan, contoh nilai yang memenuhi regex di bagian Pattern ini adalah: 2011/11/01

Bagian Substitution berisi resources yang sesungguhnya akan diakses. Resources dapat berupa lokasi file ataupun URL lain.  Pada contoh, bila pola URL di pattern dipenuhi, maka yang akan diakses adalah /post.php.  Nilai $1 akan digantikan dengan nilai ekspresi dalam tanda kurung yang pertama kali dijumpai di bagian Pattern.  Begitu juga nilai $2 akan digantikan dengan nilai ekspresi dalam tanda kurung yang kedua, dan seterusnya.

Dengan demikian, bila user yang memasukkan URL:

http://www.domain.com/2011/11/30

maka halaman yang sesungguhnya diakses adalah:

http://www.domain.com/post.php?tahun=2011&bulan=11&tanggal=30

Memakai VIM di Windows 7

Suatu hari, saya ingin melakukan perubahan konfigurasi domain GlasshFish yang ter-install di Windows 7.  Seperti kebanyakan aplikasi multiplatform lain, konfigurasi GlassFish tersimpan dalam sebuah file yang bisa di-edit oleh administrator-nya. Kebanyakan aplikasi multiplatform tidak menyimpan konfigurasi di registry, sehingga pengguna tidak dapat mengedit melalui tools GUI seperti regedit.  Hal ini masuk akal, karena registry hanya berlaku di Windows.  Cara yang paling efektif dan efisien memang dengan menuliskannya ke dalam sebuah file, karena seluruh platform lain seperti Linux, MacOS, & UNIX, dapat membaca dan menulis isi file.

Mengedit file” terdengar sangat sederhana, tetapi bagi saya, hal ini menjadi sedikit merepotkan di Windows 7, terutama bila ingin langsung mengedit sebuah file secara langsung tanpa meninggalkan Command Prompt.  Selama ini, saya tidak pernah menemukan masalah dalam mengedit file saat berada di console UNIX dan turunannya, karena hampir semua sistem operasi tersebut menyertakan editor teks VI atau VIM. Sejujurnya, saya sedikit kebingungan bila memakai VI, tetapi tidak sulit untuk men-upgrade-nya menjadi VIM (Vi IMproved).

Seandainya, saya sedang berada di Command Prompt Windows 7 (misalnya, untuk memanggil tools asadmin bawaan GlashFish), lalu saya ingin mengedit file konfigurasi domain.  Hal pertama yang saya pikirkan adalah notepad.exe, sebuah editor sederhana bawaan Windows dari berbagai generasi.  Di Command Prompt, saya bisa mengetikkan seperti berikut ini:

C:\>notepad domain.xml

Akan muncul program Notepad beserta isi file domain.xml seperti berikut ini:

Tampilan Notepad

Kenapa setiap baris jadi saling sambung menyambung seperti itu? Di platform UNIX dan turunannya (Linux, MacOS X, dan sebagainya), pemisah baris hanya satu karakter, yaitu karakter LF (Line Feed) yang diwakili karakter ASCII 10 (simbol ‘\n’).  Sementara itu, di platform Windows, pemisah baris terdiri atas dua karakter, yaitu karakter CF (Carriage Return) yang diwakili karakter ASCII 13 (simbol ‘\r’) baru diikuti dengan LF (Line Feed).  Notepad tidak menemukan karakter ‘\r\n’ sehingga tidak akan ada pemisah baris.

Masih ada sebuah solusi, yaitu editor dalam Command Prompt yang bernama edit.exe.  Sungguh tidak disangka editor yang populer di zaman DOS seperti ini masih ada di generasi Windows 7.  Untuk memakai edit.exe, saya memberikan perintah seperti berikut ini:

C:\>edit domain.xml

Akan muncul tampilan seperti berikut ini:

Tampilan Edit.exe

Sekarang file sudah dapat dibaca dan ditampilkan dengan rapi.  Akan tetapi, edit.exe memiliki banyak kelemahan dalam mengedit file.  Salah satunya adalah harus sering menggeser layar (tidak ada fitur word-wrap) dan tidak ada syntax highlighting. Bagaimana bisa fitur editor di Windows kalah dari editor VIM bawaan sistem operasi gratis seperti Linux?

Saya akhirnya memutuskan untuk menginstall VIM versi Windows di Windows 7 saya.  VIM dapat didownload di situs resmi-nya.  Untuk platform Windows, sudah tersedia installer yang dapat melakukan proses instalasi secara otomatis.

Setelah meng-install VIM, saya menambahkan direktori instalasi VIM di environment variables Path sehingga saya dapat langsung memanggil editor tersebut di Command Prompt.  Caranya adalah dengan membuka tab Advanced di System Properties.  Kemudian klik pada tombol Environment Variables… Pada dialog yang muncul, cari Path di bagian System Variables, kemudian klik Edit…  Saya menambahkan C:\Program Files\Vim\vim73 di bagian paling akhir (pisahkan dengan direktori sebelumnya dengan menggunakan tanda “;“).

Karena saya terbiasa memanggil VIM dengan mengetik vi di Linux, maka saya menambahkan symbolic link vi yang merujuk ke vim.exe. Caranya adalah dengan membuka Command Prompt sebagai superuser (tahan Ctrl+Shift) pada saat men-klik shortcut Command Prompt, lalu berikan perintah seperti berikut ini:

C:\>cd "C:\Program Files\Vim\vim73"
C:\Program Files\Vim\vim73>mklink vi.exe vim.exe
symbolic link created for vi.exe <<===>> vim.exe

Sekarang, saya dapat mengedit file konfigurasi GlassFish tersebut dengan memberikan perintah seperti berikut ini:

C:>vi domain.xml

Akan muncul tampilan seperti berikut:

Tampilan VIM

Kali ini, saya akan mendapatkan tampilan yang familiar seperti di Linux.  Tidak seperti di edit.exe, VIM secara otomatis melakukan word-wrap dan memberikan syntax highlighting (pewarnaan) sehingga lebih mudah mencari bagian yang akan di-edit.  Pertama kali memakai VIM memang bisa jadi rumit (tidak ada menu, perintah diberikan dengan mengetikkan huruf seperti :wq untuk save dan keluar).  Akan tetapi bila sudah terbiasa, VIM bisa menjadi sebuah editor yang sangat powerful.  Misalnya dengan memberikan perintah :set nu! dan :set wrap!, saya dapat mengaktifkan line number dan word wrap sehingga tampilan VIM terlihat seperti:

Tampilan VIM line number & wrap on

VIM memiliki banyak fitur menyenangkan lainnya, dan tentu saja, jauh lebih powerful dibanding edit.exe dan Notepad.exe bawaan Windows terutama bagi programmer.   Selain itu, VIM juga lebih ringan dan gratis bila dibanding editor berbasis GUI (misalnya editor komersial UltraEdit).  Dengan adanya VIM di Windows, akhirnya saya bisa sedikit lebih betah memakai console di Windows (entah mengapa masih merasa tidak seperti di Linux).

Memakai nasm Di Linux

Pada tulisan sebelumnya yang berjudul Assembly di Linux Dengan GAS, saya memperlihatkan penggunaan GNU Assembler di Linux.  GNU Assembler (GAS) hampir tersedia di kebanyakan instalasi Linux, sehingga programmer tinggal memakainya saja.  Tapi untuk memakai GAS, seseorang harus mempelajari assembly dengan syntax AT&T.  Bagi yang terbiasa dengan syntax Intel, pada awalnya mungkin akan sering mengalami sindrom “operand tertukar” (hal ini karena letak operand di syntax AT&T terbalik dengan yang ada di dokumentasi Intel).  Sebagai contoh, perhatikan syntax Intel berikut:

mov al, bl

Baris di atas akan memintahkan isi register BL ke register AL.  Untuk melakukan hal yang sama pada syntax AT&T, programmer harus memberikan perintah seperti:

movb %bl, %al

Urutan operand yang terbalik seperti ini bisa jadi membingungkan bagi programmer yang sudah terbiasa memakai syntax Intel.

Salah satu solusinya adalah dengan meng-install Netwide Assembler (NASM) yang sangat populer di Linux.  Source NASM yang terbaru pada tulisan ini dibuat dapat di-download di situs resmi NASM.  Setelah men-download dan men-extract source NASM, kerjakan script configure.  Berikan perintah make dan make install untuk meng-install NASM pada lokasi default.

Untuk melihat dukungan format NASM, berikan perintah seperti berikut:

$ nasm -hf
...
valid output formats for -f are (`*' denotes default):
* bin       flat-form binary files (e.g. DOS .COM, .SYS)
ith       Intel hex
srec      Motorola S-records
aout      Linux a.out object files
aoutb     NetBSD/FreeBSD a.out object files
coff      COFF (i386) object files (e.g. DJGPP for DOS)
elf32     ELF32 (i386) object files (e.g. Linux)
elf64     ELF64 (x86_64) object files (e.g. Linux)
as86      Linux as86 (bin86 version 0.3) object files
obj       MS-DOS 16-bit/32-bit OMF object files
win32     Microsoft Win32 (i386) object files
win64     Microsoft Win64 (x86-64) object files
rdf       Relocatable Dynamic Object File Format v2.0
ieee      IEEE-695 (LADsoft variant) object file format
macho32   NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X (i386) object files
macho64   NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X (x86_64) object files
dbg       Trace of all info passed to output stage
elf       ELF (short name for ELF32)
macho     MACHO (short name for MACHO32)
win       WIN (short name for WIN32)

Pada Linux, format yang dipakai adalah elf.  Perhatikan bahwa NASM mendukung format bin yang akan menghasilkan flat-form binary file (mirip seperti file COM di zaman DOS).  Format bin seperti ini dapat dipakai untuk menghasilkan kode untuk bootloader dan berbagai keperluan lain dalam membuat sebuah sistem operasi baru.

Berikut ini adalah program yang sama seperti pada tulisan Assembly di Linux Dengan GAS, hanya saja kali ini memakai Intel syntax dan ditujukan untuk NASM:

section .data
output_vendor:
db  `Vendor ID Prosesor adalah 'xxxxxxxxxxxx'\n`
output_vendor_length    equ     $-output_vendor

output_brand:
db  `Prosesor Brand String adalah 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'\n`
output_brand_length    equ    $-output_brand

output_no_brand:
db  `Tidak ada informasi Processor Brand String\n`
output_no_brand_length    equ    $-output_no_brand

section .text
global _start
_start:
mov    eax, 0
cpuid
mov    edi, output_vendor
mov    [edi+27], ebx
mov    [edi+31], edx
mov    [edi+35], ecx
mov    eax, 4
mov    ebx, 1
mov    ecx, output_vendor
mov    edx, output_vendor_length
int    0x80

mov    eax, 0x80000000
cpuid
cmp    eax, 0x80000004
jl    no_brand

mov    eax, 0x80000002
cpuid
mov    edi, output_brand
mov    [edi+30], eax
mov    [edi+34], ebx
mov    [edi+38], ecx
mov    [edi+42], edx

mov    eax, 0x80000003
cpuid
mov    [edi+46], eax
mov    [edi+50], ebx
mov    [edi+54], ecx
mov    [edi+58], edx

mov    eax, 0x80000004
cpuid
mov    [edi+62], eax
mov    [edi+66], ebx
mov    [edi+70], ecx
mov    [edi+74], edx
mov    [edi+77], byte 0x20

mov    eax, 4
mov    ebx, 1
mov    ecx, output_brand
mov    edx, output_brand_length
int    0x80
jmp    selesai

no_brand:
mov    eax, 4
mov    ebx, 1
mov    ecx, output_no_brand
mov    edx, output_no_brand_length
int     0x80

selesai:
mov    eax, 1
mov     ebx, 0
int    0x80

Untuk menjalankan program tersebut, berikan perintah seperti berikut ini:

$ nasm -f elf cpuinfo.asm
$ ld -o cpuinfo cpuinfo.o
$ ./cpuinfo
Vendor ID Prosesor adalah 'GenuineIntel'
Prosesor Brand String adalah 'Pentium(R) Dual-Core CPU       T4400  @ 2.20GHz '

Nilai option “-f elf” menunjukkan bahwa NASM akan menghasilkan output dalam format ELF yang dipakai oleh Linux.  Pembuat program assembler yang terbiasa menggunakan IA-32 pun dapat tetap memakai Intel syntax di platform Linux.

Menyimpan Bit Dengan Latch

Sirkuit yang outputnya tergantung pada input sebelumnya disebut sebagai sequential circuit.  Ketergantungan dengan input sebelumnya membuat sequential circuit memiliki sifat memori.  Salah satu contoh sequential circuit yang ditunjukkan dalam tulisan ini adalah apa yang disebut sebagai latches. Berikut ini adalah diagram sirkuit SR latch:

Diagram animasi SR latch

SR latch adalah sirkuit sederhana yang terdiri atas dua buah NOR gate. Sirkuit ini membutuhkan dua input, yaitu S (Set) dan R (Reset)SR latchmenghasilkan dua output, yaitu Q dan Q’.

Bila nilai S adalah 0 dan R adalah 1, maka nilai Q adalah 0.  Hal ini karena R adalah 1 dan NOR gate akan selalu menghasilkan 0 bila salah satu input bernilai 1.  Sebaliknya, nilai Q’ adalah 1.

Bila nilai S adalah 1 dan R adalah 0, maka keluaran Q’ selalu 0 sehingga Q bernilai 1.

Bila S bernilai 0 dan R bernilai 0, maka output dari Q dan Q’ akan bergantung pada nilai saat ini:

  • Nilai Q adalah 1 dan Q’ adalah 0.  Lalu, SR latch mendapat input S berupa 0 dan R berupa 0, maka nilai Q menjadi 1 dan nilai Q’ menjadi 0.
  • Nilai Q adalah 0 dan Q’ adalah 1.  Lalu, SR latch mendapat input S berupa 0 dan R berupa 0, maka nilai Q menjadi 0 dan nilai Q’ menjadi 1.

Hal ini menunjukkan bahwa:

  • Bila Set (S) bernilai 1 dan Reset (R) bernilai 0, maka nilai Q akan menjadi 0.
  • Bila Set (S) bernilai 0 dan Reset (R) bernilai 1, maka nilai Q akan menjadi 1.
  • Bila Set (S) bernilai 0 dan Reset (R) bernilai 0, maka nilai Q akan selalu sama seperti nilai sebelumnya.

Dengan demikian, sebuah SR latch dapat dipakai untuk menyimpan nilai sebuah bit.  Untuk mengatur nilai bit, seseorang perlu memberikan SR = 10 atau SR = 01.  Untuk mempertahankan nilai bit tersebut, nilai S tetap 0 dan nilai R tetap 0, maka bit Q akan selalu memiliki nilai yang sama selama listrik masih mengalir.  Ini adalah konsep dasar dari sebuah sel 1-bit dalam memori RAM.

Sequential circuit umumnya beroperasi pada synchronous mode.  Pada modus ini, seluruh sirkuit dalam sistem mengubah state-nya secara bersamaan pada waktu yang telah ditentukan, melalui penggunaan clock signal.  Sebuah clock signal adalah sinyal yang memiliki state 1 (ON) dan 0 (OFF), seperti yang ditunjukkan pada gambar berikut:

Clock Signal

Sebuah clock cycle adalah waktu diantara dua buah rising edge (sisi sinyal dari 0 menjadi 1) yang berurutan.  Clock rate atau frequency adalah jumlah clock cycle selama 1 detik dalam satuan Hertz (Hz).  Dengan demikian, frequency 1 GHz menunjukkan bahwa dalam 1 detik terdapat 1 x 109 clock cycle.  Jadi, waktu yang dibutuhkan untuk sebuah clock cycle adalah 1 / (1 x 109) = 1 x 10-9 detik atau 1 ns (nano detik).

Untuk membuat SR latch tersinkronisasi dengan keseluruhan sirkuit lainnya dalam sistem, maka diagram dapat dimodifikasi menjadi seperti pada gambar berikut:

SR latch dengan clock signal

Sekarang, input pada SR latch akan memiliki efek bila terdapat sinyal 1 (ON) dari clock.

D latch adalah jenis SR latch yang menghindari kombinasi S=1 dan R=1.  Caranya adalah dengan menggunakan sebuah inverter, seperti yang terlihat di gambar berikut:

D latch

Langkah untuk memberi nilai Q pada D latch sama seperti pada SR latch.  Setelah itu, nilai Q pada D latch akan terus dipertahankan dengan selama sinyal dari clock adalah sinyal 0 (OFF).