Systems Programming #2 (lanjutan)

03 Jan 2011 Systems Programming #2 (lanjutan)

Setelah mengetahui pengantar tentang ruang-lingkup umum systems programming pada posting sebelumnya, mungkin ada yang penasaran ingin tahu lebih jauh. Seperti dikemukakan di pengantar tersebut, systems programming menuntut porsi praktek lebih banyak ketimbang teori. Tanpa praktek, programming umum pun sangat sulit untuk dipahami. Terlebih systems programming. Mengingat eratnya hubungan antara systems programming dan arsitektur komputer, untuk membahas masalah praktek, kita harus fokus kepada salah satu arsitektur. Berhubung spesialisasi saya di mainframe (MF) maka, contoh-contoh praktek yang akan ditampilkan disini untuk MF. Bagi yang ingin mendalami MF, bisa langsung mencernanya. Tetapi bagi yang ingin mendalaminya dengan Intel, silakan baca buku-buku tentang arsitektur Intel, dan mencari padanannya dengan uraian disini. Yang terbaru adalah Intel(R) 64 and IA 32 Architectures Software Developer’s Manual, volume 1 s/d 3B.

Dongeng ini sebenarnya masih pendahuluan, sekedar mengenali teknik-teknik dasar untuk mempraktekkan systems programming. Yang tertarik mempelajarinya, perlahan-lahan dianjurkan sambil membaca buku-buku assembler. Karena, meskipun dalam praktek sebagian bisa menggunakan bahasa C, namun menjelaskan praktek systems programming tidak ada jalan lain selain menggunakan assembly. Tidak sulit, asal kita tidak alergi duluan. Anggap ringan tapi penting dan menarik! Sehingga timbul semangat mempelajarinya. Sebagai langkah awal, silakan mengenal assembly lebih dulu.

Assembler Satu-satunya Cara Mengenal Arsitektur Komputer

Si Pulan bilang, untuk mengenali arsitektur komputer cukup dengan penjelasan kata-kata dan gambar. Nah.. jelas si Pulan bohong 🙂 Dia sebenarnya hanya tahu tapi tak mengenal arsitektur komputer dan si komputer pun tak kenal dia. Jangankan arsitektur komputer, yang merupakan salah satu pelajaran inti ilmu komputer. Kadang pengetahuan IT umum saja jika hanya disajikan dalam kata-kata dan gambar sering tidak mengena sasaran. Contohnya pelajaran teknologi informatika dan komputer (TIK) di SLTP dan SLTA. Isinya bahkan hanya penjelasan bagaimana menggunakan produk-produk Microsoft. Sebenarnya tuntunan praktek Microsoft bukan? Tetapi sangat tidak mencapai sasaran. Jangankan anak-anak yang belum tahu Microsoft. Yang sudah lihaipun kewalahan. Kenapa? Karena materi praktek dibahas seperti membahas teori. Sayang hanya sebatas operasional, tidak menyentuh teori komputasi sedikitpun. Sehingga produknya bukan pengetahuan TIK, melainkan Microsoft dan beberapa produk ikutannya. Parahnya, tercipta pola pikir bahwa TIK itu Microsoft dan Microsoft itulah TIK. Mungkin tujuannya untuk mencuci otak untuk menciptakan generasi pendukung Microsoft.

Demikian pula arsitektur komputer. Mempelajari arsitektur komputer adalah mempelajari prinsip kerjanya. Cara kerja komputer secara umum mudah dijelaskan dengan tulisan dan gambar. Kita bisa berbicara lancar mengenai BIOS, RAM, processor, OS, driver, DLL dsb, bahkan bisa merangkai sendiri hardware-nya. Tetapi bagaimana prinsip kerja masing-masing benda itu tak mungkin kita pahami tanpa memahami kode-kode perintah maupun informasi yang semuanya digital. Walaupun bisa diringkas dalam hexadecimal, tentu sangat sulit dipraktekan, apalagi hanya dibicarakan. Untuk lebih mudah diingat dan dimengerti kode-kode digital tersebutg disimbolasikan. Misalnya kode 01011000 atau hex 58 yang fungsinya memuat (load) isi memori ke register tertentu, disimbolkan dengan L, singkatan LOAD. Kode hex 5A yang fungsinya menambahkan 4-byte integer di memori ke register tertentu, disimbolkan dengan A, singkatan ADD. Simbolisasi ini lantas dikenal sebagai assembly, dan itulah pentingnya menguasai assembly. Untuk mengenalinya, dimulai dari proses assembling.

Assembling adalah proses penterjemahan kode-kode instruksi assembly menjadi kode-kode instruksi mesin, kemudian dirakit menjadi sebuah modul obyek program yang siap diexekusi. Proses ini tidak melalui kompilasi, melainkan perterjemahan langsung kode per kode. L diterjemah menjadi 01011000 atau hex 58, A menjadi 01011010 atau hex 5A dan seterusnya. Jika source code kita terdiri dari 100 instruksi assembly, maka obyek yang dihasilkan juga 100 instruksi mesin. Logika program 100% karya kita. Assembler sama sekali tidak ikut campur. Jika logika yang kita susun bagus hasilnya bagus jika jelek hasilnya jelek. Karena tidak ada proses pembenahan maupun optimasi seperti yang dilakukan compiler.

Slides berikut ini menggambarkan urut-urutan proses assembling sebuah modul program sederhana. Silakan dicermati.


Program yang diproses dalam contoh di atas, bukan system program. Tersusun dari 6 instruksi assembly dan 20 bytes data untuk menghitung data5 = data1 * data3 + data6. Memang system program umumnya dibuat dengan assembly. Tapi tidak setiap program assembly selalu system program. Modul obyek program yang dihasilkan (executable) hanya 40 byte, terdiri dari 20bytes data dan 20bytes instruksi mesin (6 instruksi).

Setelah menjadi modul obyek baru komputer bisa mengexekusinya. Namun obyek harus berada di memori. Hanya ada 2 cara untuk memuat obyek ke memori. Pertama adalah melalui proses bootstrap jika komputer hidup tetapi tidak sedang menjalankan operating system (OS). Cara ini cukup panjang dan benar-benar menuntut ketrampilan systems programming yang cukup matang. Harus disediakan channel program untuk membaca obyek tadi secara fisik (tanpa bantuan filesystem. Channel program untuk bootstrap sangat kecil, hanya 24 byte, disebut boot record dan harus ditempatkan paling depan. Jika device yang digunakan tape, harus volume header. Untuk disk (DASD) bergoemetrik CKD harus di cylinder 0 track 0 record 0 dan untuk DASD FBA harus di block 0 record 0. Obyek program harus berformat deck dan letaknya dimana saja selama ditunjuk oleh boot record. Kemudian device di-boot agar boot record masuk ke memori dan diexekusi. Dari exekusi boot record inilah obyek deck lantas diangkut ke memori dan diexekusi segera setelah semua terangkut.

Jika kita menggunakan utilitas ICKDSF, kita tidak perlu menyusun boot record sendiri. Cukup dengan me-reformat device yang kita pakai mewadahi obyek kita sbb:

REFORMAT UNIT(devnum) NOVERIFY IPLDD(deck-file)

Devnum menunjuk alamat device yang kita pakai dan deck-file menunjuk definisi data (DD pada JCL) yang menunjuk ke file yang berisi obyek kita yang akan kita muat ke device tersebut. ICKDSF lantas menyalin obyek deck kita dari file tersebut ke device tersebut dan menyusun boot record yang menunjuk lokasi fisik salinan deck tersebut.

Cara yang kedua adalah menggunakan OS untuk memuat dan mengexekusi obyek kita. Cara ini adalah cara yang paling umum dan sama sekali tidak memerlukan ketrampilan apapun. Kita bahkan tidak menyadari bahwa program kita melalui tahapan ini. Karena kita tahunya hanya mengexekusi. OS lah yang melakukan pemuatan (loading) jika program kita belum di memori.

Terlepas caranya dengan bootstrap maupun menggunakan OS, memuat program ke memori tidak asal muat. Memori memang bersifat byte addressable, dimana tiap byte bisa dialamati atau diakses. Tetapi proses exekusi isi memori oleh processor selalu berbasis memory word sesuai dengan ukuran instruksi mesin terkecil dan ruang bilangan integer terkecil. Instruksi terkecil adalah 2byte (1 byte opcode dan 1 byte operand). Ruang integer terkecil juga umumnya 2 byte. Maka pemuatan memori ke processor harus kelipatan 2byte. Oleh karena itu isi memori juga harus mengikuti penataan (alignment) kelipatan 2 byte. Ini untuk menjaga jangan sampai ada instruksi yang terpotong. Jadi tidak ada instruksi di memori beralamat 038F9A1F, karena pasti akan terpotong saat diexekusi dan jadinya error. Yang mungkin adalah 038F9A1E atau 038F9A20. Demi keamanan, loader didisain untuk selalu menempatkan obyek dimulai dengan alamat kelipatan 8 (doubleword). Jika obyek kita berasal dari bahasa komputer yang dikompilasi, maka otomatis semua instruksi dan data akan aligned, karena compiler ikut membantu menata pada saat program dikompilasi. Tetapi jika program kita dengan assembly, kita lah yang harus bertanggungjawab menatanya. Jika tidak, maka program kita akan mengalami error yang sangat sulit ditelusuri karena syntax maupun logiknya benar, tapi error. Berikut ini slides untuk menggambarkan proses pemuatan modul obyek ke memori. Obyeknya adalah hasil proses assembling pada contoh di atas.

Setelah obyek tersebut masuk ke memori, lantas diexekusi. Jika loadingnya dengan proses bootstrap, maka exekusinya benar-benar segera setelah termuat. Tetapi jika dengan OS, maka OS yang mengatur penjadwalan exekusinya.

Lantas, bagaimanakah proses exekusinya di memori? Obyek yang sudah dalam kode-kode instruksi mesin kemudian diangkut ke processor cache. Pengangkutan ini bisa sekalibus maupun bertahap tergantung ukuran dan jenjang cache. MF z196 memiliki 3 jenjang cache dengan ukuran L1 = 192KB processor, L2 = 1.5MB per processor dan L3 = 24MB per 4 processor.

Dibuat berjenjang karena proses yang sebenarnya dilakukan secara pipeline. Artinya, tidak satu instruksi diproses sampai tuntas baru disusul instruksi berikutnya. Melainkan susul-menyusul. Satu instruksi baru di-encode, sudah disusul instruksi berikutnya di-load ke instruction register (IR). Saat instruksi pertama memasuki jenjang pemuatan operand, instruksi kedua di-encode dan instruksi ketiga menyusul di-load ke IR. Saat instruksi pertama memasuki tahap exekusi, instruksi kedua memasuki tahap pemuatan operand, instruksi ketiga di-encode dan instruksi keempat menyusul di-load ke IR. Saat hasil exekusi instruksi pertama di-decode, instruksi kedua diexekusi, instruksi ketiga memasuki tahap pemuatan operand, instruksi keempat di-encode dan instruksi kelima menyusul di-load ke IR. Demikian seterusnya hingga kecepatan secara keseluruhan menjadi lebih cepat dibanding jika prosesnya satu per satu.

Berikut ini slides untuk menggambarkan proses exekusi modul obyek. Tetapi sangat sulit jika ditayangkan dengan pipelining, sehingga yang ditampilkan proses satu per satu. Hanya sekedar gambaran untuk memudahkan memahami bagaimana prosesor bekerja.

Satu hal yang berlu dicatat adalah.. bahwa pipelining tidak selamanya lebih baik. Saat sebuah instruksi diexekusi (pada jenjang keempat) dan ternyata instruksi tersebut dari jenis branch (BR, BCR, BC, BASR, BAS, BALR, BAL dll) untuk meloncat ke alamat lain, maka seluruh instruksi berikutnya yang sudah memasuki pipeline dihapus dari cache. Oleh karena itu, bagi yang peduli dengan kecepatan dan kinerja program, sebaiknya hati-hati menggunakan jenis-jenis instruksi branch. Atur sedemikian rupa logik program dengan memilih algoritma yang tidak terlalu banyak branch.

Reentrancy

Selain assembly ada juga hal lain yang tak kalah pentingnya untuk menuju ke systems programming, yaitu reentrancy dan multitasking. Modul obyek program dikatakan reentrant manakala ketika diexeksi di memori tidak ada satu bit pun berubah. Artinya, modul tersebut tidak memiliki variable yang di-update sepanjang exekusinya. Logik programnya boleh saja meng-update satu atau beberapa variable, tetapi letak variable tersebut di luar modul obyek. Sehingga obyek bisa ditempatkan di memori yang terproteksi.

Umumnya sebuah obyek dimuat ke memori setiap kali diexekusi. Jika obyek yang sama diexekusi sekaligus oleh 10 job, maka obyek tersebut di-load ke memori 10 kali juga. Setiap job memiliki salinan obyek tersebut sendiri-sendiri untuk menjaga jangan sampai proses dan hasil proses obyek tersebut mempengaruhi atau terpengaruh oleh proses dan hasil proses obyek yang sama pada job lain. Kerugiannya adalah efisiensi dan kesibukan memori. Jika hal ini terjadi untuk sebuah transaksi online CICS atau web, bukan hanya 10, bahkan bisa saja ribuan salinan obyek yang sama harus nongkrong di memori pada saat transaksi yang sama dilakukan bersama atau overlapping oleh ribuan orang. Jika kapasitas memorinya terbatas, maka OS akan melakukan paging yang tentunya akan menurunkan kinerja sistem secara keseluruhan.

Tetapi jika obyeknya reentrant, berapapun jumlah job maupun transaksi yang memanggilnya secara bersamaan atau overlapping, di memori cukup satu salinan saja. OS hanya me-load sekali saja. Selama masih di memori, OS tidak perlu memuat lagi manakala ada job lain memanggil obyek tersebut.

Compiler dan linkeditor pasti menyediakan opsi RENT untuk membuat modul obyek yang dihasilkan reentrant. Namanya juga opsi, berarti bukan keharusan. Programmer yang belum berpengalaman dan tidak memiliki latarbelakang ilmu komputer sering tidak memperhatikan himbauan ini. Apesnya jika analyst ataupun pimpinan tim mereka juga tidak mengerti makna reentrancy, bisa saja sistem mengalami degradasi kinerja setiap hari gara-gara kebodohan ini.

Berbeda sekali dengan systems programming, dimana reentrancy kadang merupakan keharusan. Dalam systems programming kadang ada modul-modul obyek yang harus ditempatkan di common segment memori, entah untuk keperluan sharing informasi tertentu atau karena masuk dalam lingkup subsystem menjadi bagian OS. Untuk itu reentrancy mutlak wajib. Jika tidak reentrant, jangankan jalan, dipasang pun akan gagal.

Berbeda dengan modul program yang dibuat dengan bahasa komputer, reentrancy untuk modul program yang dibuat dengan assembly tidak cukup hanya dengan mencantumkan opsi RENT pada assembler dan linkeditor. Opsi RENT pada compiler untuk menjadikan modul obyek yang dihasilkan reentrant. Sedangkan opsi RENT pada assembly hanya untuk memeriksa apakah kode-kode yang kita susun memenuhi persyaratan menjadi modul reentrant. Artinya, kitalah yang bertanggungjawab untuk menyusun skenario logik yang reentrant. Misalnya, untuk state housekeeping maupun menyimpan nilai-nilai variable tidak menggunakan bagian dari modul tersebut, melainkan harus ditempatkan pada memori yang dialokasikan on the fly saat modul diexekusi. Dengan demikian saat diexekusi, meskipun modul obyeknya hanya satu salinan di memori, tetapi save area dan seluruh variable ditempatkan di wilayah (region) masing-masing job atau transaksi yang memanggilnya.

Multitasking

Programmer tidak selalu tahu tentang multitasking. Tahu pun kadang tidak terlibat dalam penyusunan logik multitasking. Pembuat program aplikasi CICS mungkin ada yang tidak tahu bahwa program yang mereka bikin adalah subtask atau child sebuah program induk yang bernama CICS. Mereka juga tidak dilibatkan dalam penyusunan mekanisme logik multitasking. bahkan meskipun untuk transaksi web maupun client/server dimana CICS berperan sebagai server, namun tetap saja programmer tidak dilibatkan dalam mekanisme proses multitasking.

Berbeda dengan programmer yang membuat server program, misalnya web server. Aplikasi tersebut memerlukan mekansime multitasking, dan sepenuhnya diserahkan kepada programmer. Kita bisa tahu server bikinan programmer yang tidak tahu multitasking. Susunan logik yang seharusnya asinkron dipaksakan sinkron. Pada saat diakses oleh satu browser mungkin tidak kelihatan. Begitu banyak browser yang mangaksesnya bersamaan baru akan kelihatan keganjilannya.

Multitasking merupakan metoda terbaik untuk memecahkan logik program yang asinkron. Contoh yang paling lazim adalah server. Kontak dan permintaan layanan dari client bisa datang kapan saja. Sehingga bisa saja pada satu saat hadir lebih dari satu client yang semuanya harus dilayani. Jika logik server-nya sinkron, maka pelayanan akan diberikan secara bergilir dan dampaknya akan erasa bagi client yang harus menunggu. Tetapi jika servernya multitasking, setiap client dilayani oleh subtask terpisah, sehingga tidak perlu harus menunggu. Semua dilayani secara serentak. Jika beban sistem naik dan harus ada proses yang antre, client tidak terlalu merasakan karena semua mendapatkan progress layanan.

Di jagad systems programming, kadang multitasking menjadi wajib. Misalnya dalam otomasi, dimana system-event dicegat di wilayah OS yang sangat dibatasi. Sehingga tidak mungkin memproses setiap event mulai penangkapan hingga exekusi aksi di wilayah OS. Kita harus belah menjadi 2 bagian, di wilayah OS sekecil mungkin dan sisanya dilanjutkan di luar OS (sebagai job). Job senantiasa harus siap setiap saat. Untuk itu multitasking adalah wajib agar program induk kerjanya hanya menunggu sinyal dan yang melanjutkan proses adalah subtask.

Berikut ini adalah slides yang menayangkan contoh gambaran mekanisme multitasking digabung dengan reentrancy. Kebetulan antara keduanya memiliki keakraban tersendiri. Dalam multitasking seringkali sejumlah subtask memerlukan layanan fungsi yang sama. Nah .. kita harus jeli. Fungsi-fungsi yang dierlukan lebih dari satu subtask sebaiknya dikemas dalam modul obyek yang reentrant. Jika tidak, maka setiap subtask akan memiliki salinan fungsi tersebut. Bahkan modul subtask pun sebaiknya reentrant kecuali kita yakin subtask tersebut tidak akan pernah diexekusi lagi selagi masih jalan.

Slides di atas menayangkan multitasking antara modul obyek NIT01 dan NIT02 dan keduanya memerlukan common service dari modul obyek NITSRV. Oleh karena itu modul obyek NITSRV harus reentrant. Keiga modul obyek tersebut tentu binary yang seharusnya digambarkan dalam hexadecimal. Disini terpaksa ditayangkan dalam assembly untuk sekedar memudahkan pemahaman.

Catatan Soal Multitasking

Bagi yang terbiasa dengan processor Intel(R), mungkin membayangkan bahwa struktur multitasking disediakan lengkap oleh hardware. Setiap komponen program yang ditugasi sebagai task harus dilengkapi dengan task state segment (TSS) yang otomatis akan menyimpan (stack) status semua register dan execution flags manakala exekusi task dihentikan atau suspended (mungkin gantian dengan task lain) dan di-restore (unstack) kembali ke processor manakala task diexekusi kembali. Kelebihannya, mudah diimplementasikan dalam programming. Software tidak ikut campur urusan ini, pokoknya terima beres. Kekurangannya, jumlah task terbatas, maximum sebanyak segment memori yang bisa diformat menjadi TSS.

Sedangkan di mainframe, TSS diselenggarakan oleh software (dalam hal ini OS) dengan mengkapling common segment, dinamakan task control block (TCB). Format TCB juga bebas, terserah OS. Bahkan OS boleh saja membuat lebih dari satu format TCB. Untuk task yg khusus untuk menyampaikan layanan internal OS dinamakan service request block (SRB) dan formatnya berbeda dari TCB. Hardware menyediakan linkage stack (LX), tapi yang memakainya malah program aplikasi.

Proses stack state manakala exekusi task dihentikan dan unstack state manakala task akan diexekusi kembali, juga merupakan tanggungjawab software (OS). Tidak ada register khusus terkait dengan TCB. Memang mainframe tidak memiliki register khusus seperti Intel. Kelebihannya fleksibel. TCB bisa dibentuk dan dihapus sesuaai kebutuhan dan kapasitas memori. Kekurangannya, karena semuanya tanggungjawab OS, maka OS lebih ribet.

Bersambung…

Topik-topik terkait

  1. Mengenal Assembly
  2. Memanfaatkan kesalahan dalam Assembly
  3. Systems programming
mm
Deru Sudibyo
deru.sudibyo@gmail.com
3 Comments
  • Anonymous
    Posted at 22:05h, 10 January Reply

    Wuah.. ngelihat yg ada di slide pak deru ini jago beneran soal assembler dan OS. apa bapak pernah ikutan bikin OS? btw, saya ingin belajar, gimana caranya ya? apa pak deru juga pengajar? apa sy boleh belajar sama bapak? trus, nantinya kerja dimana pak? thanks berat.

    -bud

  • Leo
    Posted at 12:30h, 11 January Reply

    saya dengar assembler & mainframe (MF) malah dari temen yg pernah kerja di malaysia. mohon info, apa bener expert mainframe ngga kalah ama expert SAP? apa bener kursus, pelatihan atau semacamnya utk MF ngga ada yg diselenggarakan di indonesia? terus gimana dunk kalo kita2 pengen belajar assembly & MF? trims pencerahannya.

    (leo)

  • Deru Sudibyo
    Posted at 13:17h, 11 January Reply

    Pak @bud,
    Ah jangan berlebihan. Saya belum pernah ikutan bikin OS, tapi pernah bikin semacam miniatur OS, sekedar melengkapi pengalaman. Mengenai belajar, jika ini kepentingan individu, mestinya sarana yg paling bagus afiliasi dg IBM Academic Initiative (IBM-AI). Dulu pernah saya tawarkan bersama pak Nasir dari IBM Jakarta ke berbagai PTN/PTS di negeri ini, tapi nggak ada sambutan. Kalo memang anda tertarik, coba nanti saya bahas dulu dengan rekan2 di NSI. Tetapi jika ini kepentingan instansi/profesional sih gampang banget. Hubungi saja NSI (zjosxdi.com). Tks.

    Pak @leo,
    Wah masalah menang kalah expert MF vs SAP saya nggak tahu. Saya kira hukum pasar yg berlaku. Tentang pelatihan, sudah saya jelaskan di atas. Memang agak sulit mencari tempat pelatihan MF. Di Singapura, Malaysia, Australia yang gudangnya MF pun biasanya harus ke US atau India. Tapi di kita ada, di NSI. Tapi khusus melayani pelatihan profesional yg tentunya dibiayai instansi masing2 peserta. Untuk pelatihan publik, mungkin perlu perlu dirembug, karena tentunya biayanya harus jauh di bawah pelatihan profesional. Tks.

    salam
    DS

Post A Reply to Anonymous Cancel Reply