CLICK HERE FOR THOUSANDS OF FREE BLOGGER TEMPLATES »

Sabtu, 20 Oktober 2007

Interpreter dan Compiler

Interpreter

Pada bahasa yang menggunakan interpreter, ada suatu program besar yang mendiami memori komputer secara terus menerus. Jika dilakukan pengetikan sebaris program, misalnya suatu pernyataan BASIC, maka interpreter ini akan mengawasi proses pemasukannya lalu menambahkan baris tersebut kedalam program yang tadi sudah tersimpan dalam memori.

Ketika menjalankan program tersebut, interpreter akan memeriksa program baris demi baris dan menterjemahkannya ke dalam bahasa mesin (satu-satunya bahasa yang dapat dimengerti oleh microprocessor) selanjutnya meminta komputer melaksanakan terjemahan itu kemudian melakukan proses yang serupa untuk baris program berikutnya.

Bahasa terinterprestasi cocok untuk pengembangan program cepat karena programmer dapat menulis program dan langsung mengeksekusinya serta melihat hasilnya. namun demikian bahasa ini memiliki beberapa kelemahan :
proses eksekusinya lamban karena interpreter harus menterjemahkan tiap baris program kedalam bahasa mesin setiap kali program dieksekusi. Program tetntunya akan berjalan lebih cepat jika seluruh bagian program diterjemahkan lebih dahulu sebelum dieksekusi,
harus adanya interpreter dalam memori komputer pada saat ingin menjalankan program. Contoh untuk kasus ini adalah disertakannya interpreter BASIC dalam PC 8088.

Compiler

Dalam bahasa terkompilasi, keseluruhan program atau sub program diterjemahkan ke dalam bahasa mesin sekaligus. Proses pengetikan dapat dilakukan dengan menggunakan pengolah kata, disisi lain terdapat program terpisah yang disebut compiler yang menterjemahkan berkas sumber ini menjadi berkas lain dalam bentuk bahasa mesin. Adapula compiler yang menyediakan editor sendiri seperti Turbo C dari Borland.
Dedicated for Light Intermutimedia
Perusahaan Software Pulsa

Konruksi Compiler

Teknik kompilasi telah lama diberikan di lingkungan pendidikan tinggi bidang komputer di Indonesia. Pembahasan dalam mata kuliah ini biasanya berkisar pada teori automata, teori kompilasi, teori grammar. Praktek teknik kompilasi pun telah diberikan di lingkungan laboratorium, walau biasanya masih terbatas pada demonstrasi hal teori, ataupun sekedar pengenalan kompiler yang ada atau banyak digunakan. Beberapa universitas telah mulai memperkenalkan penggunaan perangkat pembangun kompiler.
Telah banyak mahasiswa menggunakan dan memanfaatkan compiler/interpreter, tapi saat ini masih belum banyak muncul nama programmer Indonesia yang terlibat dalam proyek pembuatan compiler/interpreter. Mungkin hanya KILANG nya Prof. Dali S Naga (BASIC Indonesia), yang sempat terdengar, sayang sekarang sudah tidak ada jejaknya. Mungkin merilis KILANG dalam bentuk GPL seperti BWBASIC, adalah suatu langkah menarik untuk terus mengembangkan KILANG ini lebih lanjut.
Memang ada sekelompok programmer Indonesia yang sempat akan merilis bahasa pemrograman "BATAK" tetapi hingga saat ini belum terdengar kembali. Bahasa pemrograman, JAVA, BALI, MADURA, hanyalah namanya saja yang berbau Indoensia, tapi sedikit atau malah tidak ada keterlibatan pengembang dari Indonesia.
Tentu saja akan timbul pertanyaan "apa yang salah dalam pengajaran kompilasi ???" (INGAT SAYA TIDAK INGIN MENDISKREDITKAN SIAPAPUN DALAM PERNYATAAN INI). Hanya mencoba mencari langkah perbaikan yang mungkin bisa diterapkan.
Walaupun sedikit sekali atau nyaris tidak ada "lowongan pekerjaan" yang membutuhkan kemampuan mengembangkan compiler ini (silahkan baca di koran ataupun majalah), bukan berarti pengetahuan itu sama sekali tak dibutuhkan dalam dunia pemrograman sehari-hari. Pada dasarnya pengetahuan pembuatan kompiler (compiler construction) ini merupakan pengetahuan dasar komputasi yang sangat baik sekali. Pengetahuan ini dimanfaatkan pada beragam aplikasi nantinya. Misal teknik parsing, pengenalan pola teks, optimasi kode dan lain sebagainya. Bahkan suatu database engine pun di bagian "front end" selalu menggunakan parsing ini. Pengetahuan tentang kompilasi akan dapat memberikan landasan bagi programmer untuk menyusun program yang efektif dan efisien.
Ketika seseorang melakukan pemrograman, sebetulnya secara tidak sadar dia akan melakukan proses penambahan suatu bahasa. Misal pembuatan suatu fungsi (ataupun prosedur) pada dasarnya merupakan suatu proses "penambahan kosa-kata" dari bahasa pemrograman tersebut. Dari yang tadinya tidak memiliki fungsi tersebut hingga akhirnya ditambahkan suatu "vocabulary" untuk melakukan suatu fungsi tersebut. Untuk itulah pemahaman penyusunan kompiler merupakan suatu dasar yang utama dalam bidang ilmu komputer.

teknik dinamic loading

Semua plug-ins di Netscape atau modul di Apache memakai teknik yang sama, yaitu Dynamic Loading (DL). Ada beberapa terminologi lain untuk menyebutkan
teknik ini, seperti DSO (Dynamic Shared Object) atau DLL (Dynamic Link Library). Tulisan ini akan memberikan pengantar tentang bagaimana membuat program dengan memakai teknik ini.
1.Pendahuluan Dalam pembuatan sebuah program, terkadang kita tidak ingin semua fungsi diimplementasikan langsung pada program utama, karena kita mungkin belum tahu fungsi apa saja yang harus disediakan. Atau kita menginginkan pemakai program ini harus mempunyai kemungkinan untuk menambahkan fungsi-fungsi yang belum ada pada program yang akan kita tulis. Tentu saja semua itu harus dapat dilakukan tanpa harus melakukan proses rekompilasi program utama dari awal. Teknik Dynamic Loading adalah solusi yang tepat untuk merealisasikan keinginan di atas. Yang harus kita kerjakan hanyalah menulis program pokok yang mempunyai kemampuan memuatkan (loading) fungsi tambahan dan menginterpretasikan fungsi ini dengan benar. Sebelum kita membahas lebih jauh, kita harus mengetahui terlebih dahulu bagaimana tahapan proses dari file source code menjadi file yang bisa dieksekusi. Kita akan memulai dengan menulis program yang sudah tidak asing lagi bagi para pemrogram bahasa C yaitu Hello World.
#include
int main(int argc, char** argv) { printf("Hello World"); } Untuk melakukan proses kompilasi dapat dipakai perintah:
$ gcc -o hello hello.c Instruksi di atas akan melakukan proses berikut:
1.Proses kompilasi Source code hello.c dikompilasi menghasilkan file objek hello.o. Karena fungsi printf() tidak diimplementasikan di file ini, maka kompiler akan memberi catatan di tabel file objek ini bahwa fungsi printf() belum mempunyai referensi. 2.Proses linking Linker akan mencari di librari standard pengimplementasi fungsi yang tidak dapat ditemukan pada saat proses kompilasi, dalam hal ini pengimplementasi fungsi printf(). Perintah di atas secara implisit memanggil linker dan menambahkan beberapa librari standar sebagai parameter. Di sini pengimplementasi fungsi dari printf() akan ditemukan di libc yang juga ditambahkan tanpa sepengetahuan sang pemrogram. Proses linking librari ke program utama dibedakan menjadi dua tergantung dari caranya: 2.Proses linking statis (static linking). Di sini jika pengimplementasi fungsi printf() ditemukan, maka akan dikopikan ke dalam file objek hello. 3.Proses linking dinamis (dynamic linking). Di sini libc diimplementasikan sebagai shared library. Linker hanya akan mencatatkan referensi ke simbol pengimplementasi fungsi printf() pada file objek hello. Jika file program hello hasil dari proses linking statis dieksekusi, maka objek file program akan dimuatkan ke memori. Kemudian fungsi pertama, yang nama simbolnya tergantung dari sistem (contohnya __main), akan dipanggil. Fungsi ini, yang biasanya didefinisikan oleh kompiler atau librari akan melakukan seting dan initialisasi internal dan akhirnya akan memanggil fungsi utama main() yang didefinisikan oleh user. Pada cara kedua, jika program hello dieksekusi, maka objek file ini mula-mula juga akan dimuatkan ke memori. Kemudian linker dinamis (dynamic linker) akan membaca catatan referensi yang ada di file program hello yang dihasilkan oleh linker sebelumnya. Jika objek file shared library yang berisi pengimplementasi fungsi yang dibutuhkan belum dimuatkan ke memori, maka linker dinamis akan secara rekursif memuatkan objek file shared library ini ke memori. Rekursif berarti, jika suatu file shared library mempunyai referensi ke file shared library lainnya, maka objek file shared library yang lain ini juga akan dimuatkan ke memori (jika belum dimuat) dan seterusnya. Selanjutnya semua referensi yang merujuk ke simbol pengimplementasi fungsi akan diperbaharui ke posisi simbol yang aktual. Ini disebabkan posisi simbol pengimplementasi baru dapat ditentukan setelah objek file shared library dimuatkan ke memori (runtime). Dan posisi ini selalu berubah-ubah, tergantung dari banyak hal, seperti kapan objek file shared library ini dimuatkan ke memori, objek file shared library apa saja yang sudah dimuatkan ke memori dan sebagainya. Karena kita hanya akan membahas cara yang kedua, maka untuk selanjutnya terminologi librari dimaksudkan untuk merujuk ke shared library. 1.Shared Library Seperti disebutkan di atas, setiap kali objek file librari dimuatkan ke memori tidak selalu mempunyai posisi yang sama. Maka posisi simbol di dalam file libraripun mempunyai alamat yang selalu berubah. Oleh karena itu untuk mereferensi sebuah simbol, dilakukan pengalamatan berbasis zero, yaitu pengalamatan yang relatif terhadap posisi awal dari file librari. Setelah alamat posisi awal dapat ditentukan, maka referensi semua simbol di file librari dapat dihitung pada saat waktu eksekusi (runtime). Pada Program Library HOWTO [#!Wheeler!#] disebutkan tiga jenis librari, selain librari statis (static library) dan shared library masih ada dynamic loaded library. Dilihat dari arsitektur filenya, tidak ada perbedaan antara shared library dan dynamic loaded library. Pembedaan ini hanya dipandang dari sisi pemrogramnya saja. Pada shared library, proses loading dari objek file librari terjadi saat program utama dimuatkan ke memori (proses linking dinamis seperti diuraikan di atas). Sedang pada dynamic loaded library, proses loading dari file librari dapat berlangsung kapan saja selama program utama dijalankan. Proses linking ini juga sering disebut dengan runtime linking. Kita akan menamakan teknik yang memanfaatkan runtime linking ini dengan nama Dynamic Loading. Sebelum teknik ini dibahas, ada baiknya kita mengetahui aturan pemberian nama pada sebuah shared library, walaupun aturan ini tidak sepenuhnya berlaku pada dynamic loaded library. Penggunaan terminologi shared library untuk selanjutnya berlaku juga pada dynamic loaded library. Berbeda dengan jenis librari statis, shared library mempunyai dua jenis nama, yaitu soname dan real name. Soname terdiri dari awalan lib, nama dari librari, kata .so diikuti tanda titik (".") dan nomor versi mayor, seperti contohnya libhello.so.1. Real name adalah nama file librari sebenarnya yang disusun dari soname ditambah tanda titik ("."), nomor minor, dan kalau ada diikuti tanda titik (".") dan nomor release, seperti contohnya libhello.so.1.1 atau libhello.so.1.1.5. Selain kedua jenis nama di atas, masih ditambahkan satu jenis nama lagi yaitu linker name yang sama dengan soname tanpa nomor versi mayor, seperti contohnya libhello.so. Program yang membutuhkan file shared library akan melakukan referensi menggunakan jenis nama ini. Secara umum linker name adalah link ke soname dan soname adalah link ke real name. 2.API dari Dynamic Loading Kebanyakan sistem operasi menyediakan API (Application Program Interface) untuk penggunaan teknik Dynamic Loading. Sayangnya, nama-nama API ini belum ada standarnya, sehingga secara umum setiap sistem operasi menggunakan nama API sendiri-sendiri. Di sini kita akan menggunakan API dari sistem operasi Linux. Sebelum kita mulai dengan contoh program, kita akan membahas terlebih dahulu fungsi-fungsi API yang ditulis dalam bahasa program C. Deklarasi dari fungsi-fungsi ini terdapat di file header . void* dlopen(const char* filename, int flag); Fungsi ini bertujuan untuk memuatkan objek file filename ke memori. Jika pemanggilan fungsi berhasil atau file objek filename sudah ada di memori, maka fungsi akan mengembalikan sebuah handle sebagai hasilnya. Pada prinsipnya handle ini dapat dibayangkan sebagai referensi yang merujuk ke file objek filename. Namun demikian handle ini tidak boleh diinterpretasikan sebagai apapun juga, tapi hanya boleh digunakan sebagai parameter waktu pemanggilan fungsi lainnya seperti dlsym() atau dlclose(). Setiap kali fungsi ini dipanggil dengan sukses, maka librari dl akan memanajemen jumlah pemakai handle ini dengan cara menginkrementasi variabel. Parameter flag menentukan bagaimana dlopen() menangani simbol yang ada di objek filename. RTLD_LAZY dan RTLD_NOW dengan kombinasi RTLD_GLOBAL atau RTLD_LOCAL dapat digunakan untuk parameter ini. Intinya, pada RTLD_LAZY relokasi objek shared library baru dilakukan pada saat referensi di shared library untuk pertama kalinya dipanggil. Sedang pada RTLD_NOW proses relokasi dari semua objek shared library yang dibutuhkan dilakukan setelah objek filename dimuatkan ke memori. Dengan RTLD_GLOBAL, maka simbol di file shared library yang dimuatkan akan dapat dipakai oleh shared library lainnya. Kalau hal ini tidak dikehendaki maka dapat dipakai nilai RTLD_LOCAL yang juga merupakan nilai default. char* dlerror(void); Dengan fungsi ini, informasi tentang sebab-sebab terjadinya kesalahan pada proses linking dinamis dapat diakses. Pada terjadinya kesalahan, fungsi ini akan mengembalikan null-terminated character string sebagai hasilnya. Jika pada pemrosesan terakhir tidak terjadi kesalahan maka nilai NULL akan dikembalikan sebagai hasilnya. void* dlsym(void* handle, char* simbol); Setelah objek file filename dimuatkan ke memori, maka simbol-simbol di dalamnya dapat diakses dengan menggunakan fungsi dlsym(). Sebagai parameter pertama adalah handle yang merupakan hasil dari pemanggilan fungsi dlopen(). Parameter kedua simbol adalah nama fungsi atau nama variabel yang akan diakses. Jika simbol tidak ditemukan, maka fungsi akan mengembalikan NULL sebagai hasilnya. Pada kasus simbol ditemukan, maka sebuah pointer akan dikembalikan oleh fungsi ini sebagai hasilnya. Tergantung dari jenis simbol, pointer ini dapat diinterpretasikan sebagai pointer dari suatu fungsi atau variabel. Ada hal yang perlu mendapat perhatian di sini, jika fungsi mengembalikan nilai NULL. Di sini ada dua kemungkinan, yaitu simbol tidak ditemukan seperti diuraikan di atas, atau simbol ditemukan, tetapi mempunyai nilai NULL. Untuk mendapatkan informasi yang benar, dapat dilakukan dengan cara memanggil fungsi dlerror(), setelah pemanggilan fungsi ini. Jika fungsi dlerror() mengembalikan nilai bukan NULL, maka dapat dipastikan bahwa simbol tidak ditemukan. void* dlclose(void* handle); Fungsi ini adalah kebalikan dari fungsi dlopen(). Setiap kali fungsi ini dipanggil dengan sukses, maka librari dl akan memanajemen jumlah pemakai handle ini dengan cara mendekrementasi variabel. File objek yang direferensi oleh handle baru akan dihapuskan (unload) dari memori, jika sudah tidak ada lagi yang menggunakan handle ini (jumlahnya nol). 3.Contoh pemakaian Dynamic Loading Cara pemakaian API dari Dynamic Loading akan diperlihatkan di sini dengan menggunakan program demo yang sederhana. Source code program terdiri dari dua file, yaitu main.c dan simple_dl.c (Lihat list program: script-1 adalah main.c, script-2 adalah simple_dl.c dan script-3 adalah Makefile). File main.c adalah program utama yang mempunyai fungsi main(). Sedangkan file simple_dl.c adalah file modul yang berisi simbol variabel dan simbol pengimplementasi fungsi yang akan diakses dari fungsi main() dengan menggunakan fasilitas API Dynamic Loading. Dua simbol didefinisikan di dalam simple_dl.c. Yang pertama adalah simbol variabel yang didefinisikan sebagai berikut: char* info_linux = "Info Linux!"; Nama simbol variabel ini adalah info_linux yang merupakan pointer dari tipe data char. Pada pointer ini juga secara langsung dialokasikan sejumlah memori yang berisikan karakter string "Info Linux!". Simbol kedua adalah hello_world yang merupakan simbol dari pengimplementasi fungsi hello_world(). Pada prinsipnya nama simbol tidak selalu sama dengan nama pengimplementasi fungsi. Kita akan membahas hal ini secara ringkas pada bagian akhir dari artikel ini pada kasus penulisan program menggunakan C++. Simbol fungsi ini didefinisikan sebagai berikut: void hello_world(void); Fungsi ini hanya akan menampilkan kalimat "Hello world!" di layar monitor. Sebelum kita membahas kode di file main.c, kita akan mencoba untuk mengkompilasi file simple_dl.c. Untuk dapat menghasilkan shared library, pada proses kompilasi harus digunakan parameter -fPIC. PIC adalah kepanjangan dari position independent code. Dengan instruksi berikut:
$ gcc -fPIC -c simple_dl.c akan dihasilkan file objek simple_dl.o. Untuk mendapatkan file shared library simple_dl.so dari file objek ini dapat digunakan instruksi:
$ gcc -shared -o simple_dl.so simple_dl.o Untuk lebih yakin lagi, bahwa kedua simbol info_linux dan hello_world terdapat di file shared library simple_dl.o dapat digunakan program nm. Program ini adalah salah satu tools terdapat pada binutils yang dapat menampilkan simbol dari sebuah objek file. Instruksi
$ nm -g --defined-only -n simple_dl.so hanya akan menampilkan simbol global yang sudah terdefinisi. Daftar simbol akan ditampilkan secara berurutan menurut alamat relatif simbol, seperti yang terlihat di bawah ini:
00000618 ? _init 000007a0 T hello_world 00000840 A _etext 00000840 ? _fini 00001880 D info_linux 00001898 A _GLOBAL_OFFSET_TABLE_ 000018cc A _DYNAMIC 00001964 A __bss_start 00001964 A _edata 0000197c A _end Kolom kedua di atas menunjukkan tipe dari simbol. Huruf T mempunyai arti bahwa posisi simbol yang bersangkutan berada di bagian kode atau text, seperti halnya pada simbol hello_world yang adalah pengimplementasi fungsi. Sedangkan huruf D seperti pada simbol info_linux menandakan bahwa posisi simbol yang bersangkutan berada di bagian data yang terinitialisasi. Sekarang kita akan beralih membahas kode di dalam file main.c. Di sini kita mendefinisikan beberapa variabel. Dua diantaranya adalah void (*pFuncSimbol)(); dan char** pVarSimbol; Yang pertama adalah variabel pointer dari fungsi yang tidak mempunyai parameter (void) dan tidak mempunyai nilai kembali(void). Sedangkan variabel kedua adalah pointer dari character string. Sekarang kita akan membahas fungsi-fungsi yang dipakai di sini satu persatu.
handle = dlopen("./simple_dl.so", RTLD_NOW); if (!handle) { printf("Failed: %s\n", dlerror()); return 1; } Pertama-tama fungsi dlopen() akan dipanggil untuk memuatkan objek file shared library simple_dl.so ke memori. Program akan berakhir jika file ini tidak ditemukan. Jika objek file ini dapat dimuatkan ke memori dengan sukses, maka variabel handle selanjutnya dapat dipakai sebagai parameter untuk memanggil fungsi lainnya.
pFuncSimbol = (void (*)())dlsym(handle, "hello_world"); error = dlerror(); if (error) { printf("Failed(2): %s\n", error); return 1; } Fungsi dlsym() di atas dipanggil untuk mendapatkan referensi dari simbol hello_world. Jika simbol ini tidak ditemukan maka program akan berakhir. Informasi ini didapatkan dengan cara memanggil fungsi dlerror() yang akan mengembalikan hasil bukan NULL(lihat di atas tentang dlsym()). Jika simbol ditemukan, maka variabel pFuncSimbol sekarang mempunyai referensi ke simbol hello_world dari shared library simple_dl.so.
pFuncSimbol(); Dengan instruksi di atas, maka fungsi yang direferensi oleh variabel pFuncSimbol yang tak lain adalah fungsi hello_world di simple_dl.so akan dipanggil. Hasilnya dapat dilihat di layar monitor, yaitu penampilan character string "Hello world!".
pVarSimbol = (char**)dlsym(handle, "info_linux"); error = dlerror(); if (error) { printf("Failed(2): %s\n", error); return 1; } Seperti sebelumnya, di sini fungsi dlsym() dipakai untuk mendapatkan referensi dari simbol info_linux. Jika simbol ditemukan, maka sekarang pVarSimbol mempunyai referensi ke simbol info_linux yang isinya tidak lain adalah character string "Info Linux!".
printf("%s\n", *pVarSimbol); Di sini isi dari referensi pVarSimbol "Info Linux!" akan ditampilkan di layar monitor.
dlclose(handle); Setelah kita tidak membutuhkan lagi, maka kita harus menutup handle yang telah kita buka sebelumnya. Untuk menghasilkan file program main yang dapat dieksekusi, dapat digunakan instruksi seperti berikut:
$ gcc -o main main.c -ldl Dengan parameter -ldl maka pada proses linking shared library libdl.so yang mengimplementasi API Dynamic Loading akan ditambahkan. Setelah berhasil, jika program main dieksekusi maka di layar monitor akan ada tampilan sebagai berikut:
$ ./main Hello world! Info Linux! 4.Memanggil Fungsi di Program Utama dari Objek shared library Pada banyak kasus kita akan memerlukan fungsi yang sudah diimplementasikan di program utama untuk dipanggil dari objek shared library. Dari sisi objek shared library sendiri tidak ada masalah, selama fungsi ini sudah terimplementasi di program utama, karena pembuatan file shared library tidak membutuhkan proses linking. Yang menjadi kunci pokok di sini adalah, bahwa simbol fungsi di program utama harus ditambahan ke tabel simbol dinamik (dynamic symbol table). Tabel ini memuat semua simbol yang akan dapat diakses oleh semua objek shared library pada saat runtime. Hal ini dapat dilakukan dengan menambahkan parameter -rdynamic pada proses pembuatan file program utama. Parameter ini akan menginstruksikan kompiler untuk melewatkan parameter -export-dynamic pada proses linking oleh ld. Jika parameter ini tidak ditambahkan, maka tabel simbol dinamik hanya akan berisi simbol yang direferensi oleh objek shared library saat proses linking pada pembuatan file program utama. Kita akan menambahkan beberapa baris pada file main.c dan simple_dl.c untuk menunjukkan hal di atas. Pada file main.c ditambahkan sebuah fungsi hello_main() yang akan dipanggil dari file simple_dl.c.
/*============================== * Fungi tambahan di file main.c */
void hello_main(const char* txt) { printf("%s\n", txt); } Fungsi hello_main() hanya akan menampilkan isi string txt yang dilewatkan melalui parameter.
void hello_world(void) { printf("Hello world!\n");
/* ======================================== * Memanggil fungsi yang ada di file main.c */ hello_main("Saya simple_dl"); } Fungsi hello_main() di program utama akan dipanggil setelah fungsi helllo_world() ini dipanggil oleh program utama. Proses pembuatan objek shared library simple_dl.so sama seperti diterangkan sebelumnya. Pada pembuatan objek program utama, harus ditambahkan parameter -rdynamic seperti berikut:
$ gcc -rdynamic -o main main.c -ldl Hasil dari pengeksekusian program main dapat dilihat pada tampilan monitor:
$ ./main Hello world! Saya simple_dl Info Linux! 5.Fungsi _init() dan _fini() Fungsi _init() dan _fini() adalah dua fungsi khusus pada sebuah file shared library. Fungsi _init() akan dipanggil oleh librari dl setelah sebuah objek file shared library dimuatkan ke memori dengan instruksi dlopen(). Sedang sebelum shared library dihapuskan(unload) dari memori lewat instruksi dlclose(), librari dl akan memanggil fungsi _fini(). Kita dapat memanfaatkan kedua fungsi ini dengan cara mengimplementasikan kedua fungsi tersebut dalam shared library yang kita tulis. Pada umumnya fungsi _init() digunakan untuk menginitialisasi variabel ataupun mengalokasi memori. Fungsi _fini() sebaliknya dapat digunakan untuk menghapuskan memori yang dialokasi sebelumnya. Untuk menghindari pengimplementasian ganda, pada saat proses kompilasi pembuatan shared library harus ditambahkan parameter -nostartfiles, seperti contohnya:
$ gcc -shared -nostartfiles -o simple_dl.so simple_dl.o 6.Penggunaan C++ Pada penggunaan bahasa C++ ada beberapa aspek yang perlu mendapat perhatian. Salah satu hal yang membedakan antara C++ dan C adalah, bahwa di C++ kita dapat mempunyai beberapa fungsi dengan nama yang sama tetapi parameter yang berbeda. Terminologi yang sering dipakai untuk ini pada bahasa yang mendukung object oriented adalah overloading. Lain dengan bahasa C, di sini nama fungsi saja tidak cukup untuk dijadikan sebagai identitas yang unik (unique identifier) di tabel simbol. Untuk mendapatkan identitas yang unik ini, akan dilakukan proses mangling terhadap nama fungsi di C++ yang menyertakan informasi parameternya. Misalnya saja dengan memakai gcc, simbol fungsi foobar dengan parameter tunggal int akan berubah menjadi foobar__Fi. Proses mangling ini bergantung kepada jenis kompiler, sehingga pada pemakaian kompiler yang berbeda akan dihasilkan identitas unik yang berbeda juga. Dengan menggunakan program c++filt yang juga terdapat dalam paket binutils, kita dapat melakukan proses demangling, yaitu proses kebalikan dari mangling. Contohnya dengan intruksi
c++filt foobar__Fi maka dari simbol foobar__Fi kita akan mendapatkan kembali nama fungsi dengan parameternya foobar(int). Hal di atas akan membuat masalah pada pembuatan program yang memakai bahasa C dan C++, karena simbol fungsi program yang ditulis dengan C juga akan dilakukan proses mangling. Sebagai contoh kita ingin menulis program yang memakai librari dari pihak ketiga yang hanya memberikan file header dan file objek shared library yang ditulis dengan bahasa C. Sedangkan program yang kita tulis menggunakan bahasa C++ yang akan memanggil beberapa fungsi di librari ini. Pada proses kompilasi, simbol fungsi di file header akan dilakukan proses mangling, sehingga pada proses linking akan mengakibatkan kesalahan, karena simbol tidak dapat ditemukan. Untuk mencegahnya, simbol fungsi pada file header tidak boleh dilakukan proses mangling oleh kompiler. Ini dapat dilakukan dengan menambahkan deklarasi extern "C" di file header yang akan membuat kompiler untuk memakai konvensi nama C (C name convention). Karena pada kompiler C++ biasanya didefinisikan makro __cplusplus maka penambahan header dapat dilakukan sbb:
#ifdef __cpluplus extern "C" { #endif
......
#ifdef __cpluplus } #endif Jika librari dimuatkan menggunakan Dynamic Loading dan fungsi di librari dipanggil dengan memakai fungsi dlsym(), maka masalah di atas tidak akan terjadi, karena pada simbol fungsi di librari tidak dilakukan proses mangling. Masalah lain yang timbul sehubungan dengan pemakaian bahasa C++ adalah kita tidak dapat memakai fungsi dlsym() untuk memanggil fungsi di librari yang ditulis memakai bahasa C++. Hal ini diakibatkan karena pada semua simbol akan dilakukan proses mangling, sehingga kita tidak akan tahu nama simbol dari fungsi yang kita inginkan. 7.Penutup Penerapan teknik Dynamic Loading akan memudahkan pengembangan suatu aplikasi besar yang dilakukan oleh sekelompok pemrogram seperti halnya aplikasi web server Apache. Program utamanya hanya mengimplementasi fungsi pokok saja, sedang fungsi-fungsi lainnya ditambahkan dalam bentuk modul secara fleksibel bergantung dari keperluan. Salah satu faktor yang tidak menguntungkan adalah lamanya waktu proses pemuatan file shared library ke memori dan proses pereferensian dari simbol. Jika modul-modul dimuatkan hanya pada saat awal saja, maka faktor di atas tidak terlalu penting. Aplikasi bot irc eggdrop memakai teknik lain untuk menghindari faktor di atas. Pengaksesan ke simbol dilakukan dengan melalui tabel yang berisikan pointer statis dari simbol. Akhir kata, semoga artikel ini bermanfaat dan dapat menambah wacana teknik pemrograman bagi pembaca.

simulator Prosesssor

Simulator Prosesor
Di samping simulator mesin teori, seringkali dalam memahami proses kompilasi perlu penjelasan dari tingkat instruksi di level prosesor. Untuk itu penjelasan akan lebih mudah dilakukan bila memanfaatkan suatu simulator prosesor. Memang sebetulnya pengetahuan instruksion set design ataupun simulator ini diperoleh di Arsitektur Komputer. Akan tetapi simulator prosesor ini dapat juga dimanfaatkan untuk memberikan pemahaman teknik pembuatan dan ekseskusi suatu kompilasi. Sehingga tahapan "menjalankan kompiler, dan hasil kompilasi yang dibentuk dapat berupa" : Program aplikasi bahasa A V Kompiler/interpreter bahasa A V Bahasa mesin prosesor X V Simulator prosesor X V Sistem Operasi "Host" (misal Windows, Linux dll)
Dengan cara itu mahasiswa dapat mempelajari bagaimana proses kompilasi dilakukan dan bagaimana dijalankan pada mesin virtualnya. Sehingga pengamatan dapat dilakukan dg mudah. Faktor lain adalah dg menggunakan "prosesor virtual" maka kita dapat mendefinisikan :
Prosesor X adalah suatu prosesor virtual yg sederhana
Bahasa A merupakan bahasa yg didisain mahasiswa secara sederhana (misal hanya bisa interger, dan operasi sederhana saja)
Kompiler yg disusun akan menghasilkan "kode biner" untuk proesor X yg sederhana tersebut (misal register terbatas, dan metoda pengalamatan terbatas)
Dengan cara di atas, student tidak dihadapi oleh "instruction set" yang kompleks, dan architecture processor, dan juga bahasa pemorgraman yg rumit. Tetapi konsep kompilasi dapat lebih mudah dipahami secara mendasar. ketimbang harus menggunakan prosesor "real" dan bahasa "real" yang jelas memiliki scope sangat luas.
Berikut ini adalah beberapa simulator prosesor yang dapat dimanfaatkan dalam memberikan pemahaman lebih dalam mengenai teori dan praktis kepada para mahasiswa.
mic1. mic1 ini berbasiskan Java yang mengimplementasikan arsitektur mikro Mic-1 pada Bab 4 buku Andrew S. Tanenbaum, Structured Computer Organization,http://www.ontko.com/mic1/
DLXOS. Merupakan suatu sistem "komputer" yang dijelaskan pada buku Arsitektur oleh Hennessy & Patterson. Sistem ini terdiri dari DLX Processor (instruction set dan spesifikasi), DLX hardware simulator, DLX compiler dan assembler, DLX Operating System. Karena semua tersedia source code, jadi dapat menjelaskan secara gamblang, bagaimana suatu sistem komputer dibangun, dari "prosesor" hingga "sistem operasi".http://www.cse.ucsc.edu/~elm/Software/Dlxos/index.shtml
MIX. Emulator ini ditulis oleh David A Smallberg (1982), dan mensimulasikan prosesor MIX (yang diteragnkan dalam buku milik Donald Knuth).http://www.swiss.ai.mit.edu/~adler/MIX/
MIXAL. Merupakan lingkungan mensimulasikan kerja MIX, MIX adalah model komputer yang merupakan penyederhanaan model CISC (Complex Instruction Set Computer), assembly dari model ini mirip dengan komputer sesungguhnya. Di situ ini terdapat tutorial dan juga SIMULASI GRAFIS.http://www.gnu.org/software/mdk/mdk.html
MMIX MMIX merupakan prosesor teoritis ciptaan Prof. Donald Knuth, yang merupakan penmgembangan dari MIX. Prosesor bertipe Reduced Instruction Set Computer (RISC).http://bitrange.com/mmix/Untuk informasi lainnya tentang prosesor ini dapat dibaca di URL berikut inihttp://www-cs-faculty.stanford.edu/~knuth/mmix.htmlhttp://mmixmasters.sourceforge.net/

sejarah pascal

1. Sejarah PASCAL
merupakan pengembangan dari bahasa ALGOL 60, bahasa pemrograman untuk sains komputasi. Tahun 1960, beberapa ahli komputer bekerja untuk mengembangkan bahasa ALGOL, salah satunya adalah Dr. Niklaus Wirth dari Swiss Federal Institute of Technology (ETH-Zurich), yang merupakan anggota grup yang membuat ALGOL. Tahun 1971, dia menerbitkan suatu spesifikasi untuk highly-structured language (bahasa tinggi yang terstruktur) yang menyerupai ALGOL. Dia menamainya dengan PASCAL (seorang filsuf dan ahli matematika dari Perancis) Pascal bersifat data oriented, yaitu programmer diberi keleluasaan untuk mendefinisikan data sendiri. Pascal juga merupakan teaching language (banyak dipakai untuk pengajaran tentang konsep pemrograman). Kelebihan yang lain adalah penulisan kode Pascal yang luwes, tidak seperti misalnya FORTRAN, yang memerlukan programmer untuk menulis kode dengan format tertentu. Bentuk dasar program Pascal adalah seperti berikut:
program TITLE ;begin pernyataan;pernyataanend.
2. PASCAL
sebagai bahasa terstrukturSebagai bahasa terstruktur, PASCAL mempunyai ciri-ciri sebagai berikut:1. BerurutanSusunan dari kode-kode dalam teks Pascal harus ditulis secara urut dari atas, pernyataan-pernyataan yang ditulis lebih awal akan dieksekusi lebih dahulu. Oleh karena itu, suatu pernyataan yang menyangkut suatu variabel di dalam program, maka variable itu harus terdefinisi dahulu sebelumnya. Hal ini terutama menyangkut pada pemanggilan sub-program oleh sub-program yang lain. Bisa dibaca lebih lanjut pada bagian sub-program.2. Blok dengan batas-batas yang jelas.Pascal memberikan pembatas yang jelas pada tiap-tiap blok, seperti pada blok program utama, sub-program, struktur kontrol (pengulangan/ pemilihan), dll. Pemakaian kata kunci begin untuk mengawali operasi pada blok dan end untuk menutupnya memudahkan programmer menyusun programnya dengan mudah. Seperti contoh:
If X>0 thenbegin Write ( ‘ bilangan positif’);Writeln ( ‘ program selesai’);end;
3. Satu pintu masuk dan satu pintu keluar pada blok pemilihan dan pengulangan. Contoh di atas juga mengilustrasikan pintu masuk tunggal pada suatu blok pemilihan yaitu suatu test logika X>0, dengan pintu keluaran yang satu pula (satu disini maksudnya bukan dua baris perintah output tapi suatu paket perintah yang dirangkai dengan begin .. end.3. Bakuan PASCALDibakukan oleh ISO pada tahun 1983 dan dikembangkan dalam beberapa versi, diantaranya: USCD PASCAL, MS PASCAL, TURBO PASCAL dll. Dengan semakin berkembangnya teknologi dalam komputasi, Pascal dimanfaatkan untuk pengembangan DELPHI (berasal dari nama suatu kota di masa Yunani kuno), suatu bahasa pemrograman visual yang menonjolkan pada efek grafis dan orientasi pada objek-objek yang siap dipakai, karena memiliki Visual Component Library (VCL).
4. Struktur Bahasa PASCAL
secara umumPascal mempunyai struktur sebagai berikut:1. Bagian Judul Program2. Bagian Deklarasia. Deklarasi tipe data (TYPE)b. Deklarasi variabel (VAR)c. Deklarasi konstanta (CONST)d. Deklarasi label (LABEL)e. Deklarasi sub-program (PROCEDURE dan FUNCTION)3. Bagian Program Utama Perintah-perintah.
Teks Pascal setidaknya memiliki bagian Judul Program, bagian Deklarasi, dan Bagian Program Utama yang berupa perintah-perintah. Sedangkan untuk bagian deklarasi menyesuaikan dengan isi dari program itu sendiri. Contoh program PASCAL:
program TAMBAH_00; { Menjumlahkan dua bilangan yang nilainya diberikan dalam perintah}var X, Y, Z: integer; { Deklarasi variabel X,Y dan Z sebagai bilangan bulat }BEGIN { Program Utama Mulai }X := 50; { Perintah memberikan nilai 50 pada var. X }Y := 25; { Perintah memberikan nilai 25 pada var. Y }Z := X + Y; { Perintah menjumlahkan X dan Y serta menyimpan hasilnya ke Z}END. { Akhir Program Utama }
Pada contoh ini nilai X dan Y tidak bisa sembarang, karena didefiniskan tertentu. Agar nilai X dan Y bisa bebas ditentukan, nilai X dan Y dibaca dari default input.
program TAMBAH_01; { Menjumlahlan dua buah bilangan yang dibaca dari default input }var X, Y, Z: integer; { Deklarasi variabel X,Y dan Z sebagai bilangan bulat }BEGIN { Program Utama Mulai }read(X); { Membaca nilai X lewat key-board }read(Y); { Membaca nilai Y lewat key-board }Z := X + Y; { Menjumlahkan X dan Y serta menyimpan hasilnya ke Z }write(Z); { Menyajikan Z ke layar monitor }END. { Akhir Program Utama }
Dasar Bahasa PASCAL
Unsur-unsur Pemrogramana. Mendapatkan data dengan membaca data dari default input (key board, file atau sumber data lainnya).b. Menyimpan data ke dalam memori dengan struktur data yang sesuai,c. Memproses data dengan instruksi yang tepat.d. Menyajikan atau mengirimkan hasil olahan data ke default output (monitor, file atau tujuan lainnya).
Dalam mengolah data diperlukan pengelolaan instruksi terstruktur:a. Beberapa instruksi dikelompokkan dalam satu blok atau model yang mengerjakan tugas tertentu.b. Beberapa perintah dilaksanakan dengan persyaratan tertentu.c. Beberapa perintah dilaksanakan berulang dengan jumlah pengulangan tertentu. Identifier Digunakan untuk nama: Program, Sub-program (procedure dan function),nama: Variable, Constant, Type, Label.Nama-nama ini digunakan untuk pemakaian dan pemanggilan dalam program. Ketentuan penulisan identifiera. Nama identifier harus dimulai dengan karakter huruf alfabet: a sampai z, A sampai Z atau karakter ‘_’ (underscore - garis bawah)b. Karakter berikutnya boleh karakter numerik (0 .. 9) atau kombinasi alphanumerik (huruf-numerik).c. Panjang nama, pada berbagai versi Pascal umumnya antara 32 - 63.d. Tidak boleh menggunakan karakter istimewa: + - * / \ = < > [ ] . , ; : ( ) ^ @ { } $ # ~ ! % & ` ” ‘ dan ? Contoh penulisan:Penulisan yang benar: X _PQR Beta Sudut_Alpha luasLingkaranPenulisan yang salah: 3D sisi-Kanan B#
Jenis identifiera. Identifier umumMerupakan identifier yang didefinisikan sendiri oleh pemrogram. Pemrogram mempunyai kebebasan untuk menentukan nama identifiernya, dengan syarat nama tersebut tidak sama dengan identifier standar dan reserved word yang akan dibahas lebih lanjut. Hal ini untuk mencegah kesalahan yang bisa timbul akibat tumpang tindih identifier dalam program.b. Identifier Standar (Baku)Merupakan identifier yang didefinisikan oleh pembuat kompiler Pascal. Biasanya pembuat kompiler menyediakan suatu library yang sudah ada didalam kompiler. Library berisi berbagai procedure, fungsi atau unit yang sudah siap pakai. Misalnya Turbo Pascal Windows 1.5 memiliki suatu unit untuk memproses output yaitu wincrt, gotoxy, yang dengan mudah bisa dipakai oleh programmer di dalam menuliskan kode-kode programnya. Dinamai Identifier Standar karena suatu kompiler tidak harus memilikinya, masing-masing kompiler dimungkinkan mempunyai identifier yang berbeda untuk suatu tugas yang hampir sama. Misalnya Turbo Pascal versi DOS menggunakan crt untuk melakukan fungsi yang sama dengan wincrt (TPW 1.5). Beberapa Identifier Standar yang dimiliki oleh kompiler-kompiler Pascal antara lain:
abs arctan boolean char cos dispose eof eoln exp false input integer ln maxint new odd ord output pack page pred read readln real reset rewrite round sin sqr sqrt succ text true trunc write writeln
c. Identifier “reserved word”, yaitu yang sudah didefinisikan dan digunakan oleh bahasa PASCAL sendiri (Kita tidak bisa menamai identifier kita dengan ini).
and array begin case const div do downto else end file for forward function goto if in label mod nil not of or packed procedure program record repeat set then to type until var while with
Deklarasi Variable:Mendeklarasikan varibel adalah:a. Memberikan nama variabel sebagai identitas pengenalb. Menentukan tipe data variabelContoh deklarasi variabel:
var K : integer;R : real;C : char;T : boolean;
Beberapa identifier yang sejenis bisa dideklarasikan bersamaan.
var i, j, k : integer;{Variabel i, j dan k sebagai integer}namaMHS, alamatMHS : char; {Nama dan alamat mahasiswa }
Deklarasi Konstanta:Mendeklarasikan konstanta adalah:a. Memberikan nama konstanta sebagai identitas pengenalb. Menentukan nilai konstantaContoh deklarasi konstanta:
const MaximumSize = 100; {integer }ExitCommand = ‘Q’; {char }
Tipe Data
Tipe data yang disediakan oleh PASCAL meliputi:1. Tipe Data Sederhanamerupakan tipe data dasar yang sering dipakai oleh program, meliputi: integer (bilangan bulat), real (bilangan pecahan), char (alphanumerik dan tanda baca), dan boolean (logika). Untuk data integer dan real masing-masing terbagi menjadi beberapa kategoria. Bilangan Integermerupakan tipe data berupa bilangan bulat, terbagi atas beberapa kategori seperti terlihat dalam tabel 1. tabel 1 menunjukkan jenis data, ukuran dalam memori dan rentang nilainya.
tabel 1. Tipe Data Bilangan Integer
Tipe Data
Ukuran Tempat
Rentang Nilai
Byte
1 byte
0 s/d +255
Shortint
1 byte
-28 s/d +127
integer
2 bytes
-32768 s/d 32767
Word
2 bytes
0 s/d 65535
Longint
4 bytes
2147483648 s/d 2147483647
Contoh bilangan integer adalah: 34 6458 -90 0 1112 Penggolongan tipe data integer tersebut dimaksudkan untuk membatasi alokasi memori yang dibutuhkan misalkan untuk suatu perhitungan dari suatu variabel bilangan diperkirakan nilai maksimumnya 32767 kita cukup mendeklarasikan variabel bilangan sebagai integer (2 byte), daripada sebagai longint(4 byte). Di dalam kompilernya, Pascal menyediakan konstanta untuk bilangan Integer yaitu: MaxInt and MaxLongInt, pemrogram bisa menggunakannya di dalam programnya tanpa harus terlebih dahulu mendefinisikannya.-MaxInt bernilai 32.767-MaxLongint bernilai 2.147.483.647.contoh:
Program display_maxint;uses wincrt;begin writeln (maxint)end.
Hasilnya: 32.767
b. Bilangan RealBilangan real atau nyata merupakan jenis bilangan pecahan, dapat dituliskan secara biasa atau model scientific . Contoh bilangan real: 34.265 -3.55 0.0 35.997E+11, dimana E merupakan simbol perpangkatan 10. Jadi 452.13 mempunyai nilai sama dengan 4.5213e2. Penggolongan tipe data bilangan real dapat dilihat pada tabel 2.tabel 2. Bilangan Real
Tipe Data
Ukuran Tempat
Rentang Nilai
real
6 bytes
2.9 x 10-39 s/d 1.7 x1038
single
4 bytes
1.5 x 1045 s/d 3.4 x 1038
double
8 bytes
5.0 x 10-324 s/d 1.7 x 10308
extended
10 bytes
3.4 x 10-4932 s/d 1.1 x 104932
comp
8 bytes
-9.2x 1018 s/d 9.2x 1018
c. Chartipe data ini menyimpan karakter yang diketikkan dari keyboard, memiliki 266 macam yang terdapat dalam tabel ASCII (American Standard Code for Information Interchange). Contoh: ‘a’ ‘B’ ‘+’, dsb. Yang perlu diingat bahwa dalam menuliskannya harus dengan memakai tanda kutip tunggal. Jenis data ini memerlukan alokasi memori sebesar 1(satu) byte untuk masing-masing data.