Percobaan I Compiler Bahasa C dan Bahasa Assembly Intel ® x86 Aldo Erwin Manurung (14S14022) Tanggal Percobaan : 26/09/2016 NWS3103 Praktikum Arsitektur Sistem Komputer Laboratorium Sistem Digital – Teknik Elektro Institut Teknologi Del
Abstrak—In the first module of this course, there are nine task that relating to the compilation of C Language program and Assembly Language. The software used for the first module is the GNU C Compiler (GCC), Codeblock, Notepad++, and HexEdit. The experiments were performed that stages of compiling, comparing the results of each phase compilation, compilation techniques with GCC, comparing results compilation is done with Makefile and batchfile, and the use of stack memory on a procedure call. At the last of the experiment (the 9th experiment), the students asked to make Fibonacci program in C Language. From the first module, the students expected to understand stages of the compilation of the C Language to be Machine Language, and be able to compile it with GCC, makefile, and batch file. The others, the students are also expected to understand and to analyze Intel X86 Assembly Language and know to use stack memory on procedure calls.. Keyword—Assembly Language, Compilation, Stack Memory
GCC,
Optimation,
I. PENDAHULUAN
P
ada proses pembuatan program di beberapa platform electronic device, umumnya menggunakan Bahasa tingkat tinggi karena bahasa lebih mudah dimengerti dan dipahami oleh manusia seperti halnya Bahasa C. Di satu sisi Bahasa tingkat tinggi mudah dipahami dan dimengerti oleh manusia, namun hal sebaliknya terjadi pada mesin (mikroprosesor) yang tidak dapat mengerti Bahasa tingkat tinggi. Oleh karena itu, diperlukan suatu Bahasa yang dapat menjadi penghubung antara kedua Bahasa tersebut (dari Bahasa tingkat tinggi ke Bahasa tingkat rendah). Kemudian dibuatlah Bahasa Assembly yang menjadi solusi sebagai penerjemah pemrograman dengan Bahasa tingkat tinggi menjadi Bahasa tingkat rendah yang berisi urutan instruksi yang dimengerti oleh mesin. Selanjutnya, urutan instruksi tersebut akan dikemas kedalam suatu bentuk executable object program yang disimpan dalam bentuk file biner. Proses penerjemahan dari Bahasa tingkat tinggi menjadi Bahasa Assembly (Bahasa tingkat rendah) yang dimengerti oleh mesin disebut compilation. Dari sisi instruction set (kumpulan instruksi dalam Bahasa mesin), terdapat dua
penggolongan mesin (mikroprosessor) yaitu Complex Instruction Set Computer (CISC), contohnya miroprosessor Intel®, dan Reduce Instruction Set Computer (RISC), contohnya MIPS32®. Pada praktikum modul 1 ini, diharapkan praktikan mencapai beberapa tujuan, yaitu : 1. Praktikan memahami tahap-tahap kompilasi program dalam Bahasa C sebagai Bahasa tingkat tinggi hingga diperoleh Bahasa tingkat rendah yang dapat dieksekusi oleh mesin. 2. Praktikan mampu melakukan kompilasi program bahaca c menggunakan compiler GCC beserta penggunaan makefile dan batch file. 3. Praktikan memahami Bahasa assembly dan mampu melakukan analisis terhadap Bahasa assembly Intel® x86 yang dihasilkan oleh compiler GCC. 4. Praktikan memahami pengunaan stack memory pada setiap procedure call. II. LANDASAN TEORETIS A. Kompilasi Menggunakan GCC Proses menerjemahkan baris kode program dalam bahasa C menjadi file executable dilakukan dalam empat langkah yaitu preprocessor, compiler, assembler, dan linker yang seluruhnya disebut sistem kompilasi seperti ditunjukkan pada diagram berikut:
Preprocessor Semua perintah preprocessor yang ditulis dalam bahasa tingkat tinggi akan diproses terlebih dahulu oleh preprocessor sebelum compiler melaksanakan tugasnya. Beberapa tugas dari preprocessor ini adalah sebagai berikut. o Semua komentar dalam file program diganti degan spasi satu buah. o Semua \n (backslash-newline) yang menandakan baris
baru akan dihapus tidak peduli dimanapun dia berada. Fitur ini memungkinkan kita untuk membagi baris program yang panjang ke dalam beberapa baris tanpa mengubah arti. o Macro yang telah didefinisikan diganti dengan definisinya.
C. Optimisasi Program melalui Proses Kompilasi GCC mendukung beberapa tingkat optimisasi program yang dapat dilakukan saat proses kompilasi dilakukan. Terdapat beberapa tingkat optimisasi program yang dapat dipilih dengan menambahkan flag optimisasi saat melakukan kompilasi program. Umumnya optimisasi program merupakan trade-off antara execution speed, program size, compilation time, dan kemudahan dalam melakukan debugging.
Contohnya, pada perintah #define MAX_ROWS 10, preprocessor akan mengganti semua kata MAX_ROWS dengan 10. Pada perintah #include , preprocessor akan mengganti baris tersebut dengan isi file stdio.h. Compiler Compiler akan menerjemahkan bahasa tingkat tinggi C menjadi kode assembly. Kode assembly ini berisi instruksi-instruksi yang sesuai dengan instruction set yang dimiliki oleh mesin. File yang dihasilkan pada tahap ini masih berupa file teks (.s). Assembler Assembler akan menerjemahkan bahasa assembly menjadi file objek. File objek ini merupakan file biner (.o). Linker Linker akan menggabungkan file biner yang diperoleh pada tahap sebelumnya dengan file biner lain yang merupakan dependency dari program yang dibuat, contohnya library untuk menjalankan fungsi printf. Hasil dari linker berupa file biner executable (dalam platform Microsoft® Windows™, file ini memiliki akhiran .exe).
gcc –O2 -o Program.exe Program.c
Untuk melakukan proses kompilasi menggunakan GCC, dapat digunakan Command Prompt pada Microsoft® Windows™. B. Disassembly menggunakan GCC Selain dapat melakukan kompilasi, paket compiler GCC juga menyertakan sebuah disassembler yang mampu melakukan disassembly file biner (.o atau .exe) menjadi file assembly (.s) bernama Object Dump. Untuk melakukan disassembly, kita dapat menggunakan perintah berikut. objdump -d Program.o objdump -d Program.exe Hasil dari proses disassembly ditampilkan pada jendela Command Prompt. Agar hasil dari proses disassembly dapat disimpan ke dalam suatu file, kita dapat menggunakan perintah berikut objdump -d Program.o > Program.s objdump -d Program.exe > Program.s
Dengan demikian, hasil proses disassembly akan disimpan dalam file Program.s.
Flag –O2 tersebut menandakan bahwa proses kompilasi dilakukan dengan optimisasi tingkat dua. Beberapa flag optimisasi yang dikenali oleh GCC adalah –O0, –O1, – O2, –O3, –Os, dan –Ofast. Perbedaan masing-masing level optimisasi diberikan sebagai berikut. -O0 : tidak melakukan optimalisasi sama sekali namun mengorbankan waktu kompilasi yang lama, dan menggunakan RAM yang amat besar baik selama proses kompialasi atau binari nantinya, namun baiknya binari akan sangat stabil. -O1 : opstimasi yang dilakukan sedikit dan menghasilkan waktu kompilasi yang lama, binary berukuran besar, dan memakan banyak RAM. -O2 : optimalisasi lebih ditingkatkan (dari –O1), waktu kompilasi lebih cepat, menghasilkan binari dengan ukuran tidak terlalu besar dan lebih sedikit menggunakan RAM -O3 : optimalisasi penuh, memanfaatkan multithreading, waktu kompilasi yang cepat, binari berukuran kecil dan menggunakan RAM seminum mungkin binarinya nanti, namun potensi crash amat besar jika sistem tidak mendukung atau source code tidak mendukung opsi ini. -Os : optimasi dilakukan dengan mengoptimalkan pada ukuran yang kecil pada binari saja, -Ofast : mengaktifkan semua optimasi pada –O3 dan pilihan –ffast-math dan fortrand specific D. Makefile dan Batch File GCC memiliki fitur makefile yang berfungsi untuk menulis daftar nama file kode di dalam project tersebut. Kita cukup memberikan GCC nama makefile lalu GCC akan melakukan proses kompilasi untuk semua file tersebut untuk kemudian menggabungkannya pada file executable. Makefile dapat bersifat sederhana hingga kompleks, bergantung pada sejauh mana kita menggunakan makefile untuk mengorganisasikan project kita. Contoh isi dari makefile adalah sebagai berikut.
E. Instruksi dan Bahasa Assembly Intel® x86 Arsitektur mikroprosesor Intel® x86 merupakan salah satu arsitektur mikroprosesor yang banyak digunakan. Dengan mempelajari bahasa assembly dan instruksi Intel® x86, kita akan sangat terbantu dalam melakukan proses debugging dan optimisasi program yang kita buat. Dalam mikroprosesor Intel® x86, terdapat banyak register yang dapat digunakan. Namun, pada praktikum kali ini, kita cukup mempelajari beberapa register berikut. GCC dapat diperintahkan untuk melakukan kompilasi makefile dengan perintah sebagai berikut. mingw32-make -f makefile Perintah tersebut akan melakukan kompilasi terhadap makefile yang diberikan menjadi sebuah program bernama contoh.exe. Program ini dihasilkan oleh hasil linker terhadap dua file objek bernama main.o dan text.o (tentunya termasuk dengan library yang lain yang dibutuhkan). Untuk memperoleh main.o, GCC harus melakukan kompilasi source code main.c menjadi file objek. Begitupula untuk memperoleh text.o, GCC harus melakukan kompilasi source code text.c. Pada platform Microsoft® Windows™, terdapat sebuah file shell script bernama Windows™ Batch File. Kita dapat menuliskan perintah-perintah yang biasa kita tuliskan secara terpisah pada command prompt dalam suatu file yang disimpan dengan ekstensi .bat. Untuk mengeksekusi perintahperintah tersebut, kita cukup menjalankan file .bat tersebut sehingga command prompt terbuka dan perintahperintah yang kita tuliskan dieksekusi secara otomatis. Contoh Windows™ Batch File adalah sebagai berikut. %~d0 cd "%~dp0" gcc -O2 -E code.c > Program.l gcc -O2 -S code.c gcc -O2 -c code.c gcc -O2 -o code.c pause objdump -d code.o > dump_o.dmp objdump -d prog.exe > dump_exe.dmp pause
Windows™ Batch File tersebut berisi perintah sebagai berikut. Perintah %~d0 memerintahkan command prompt untuk berpindah drive letter ke drive letter yang sesuai dengan lokasi Windows™ Batch File berada. Selanjutnya, perintah cd "%~dp0" memerintahkan command prompt untuk berpindah folder ke lokasi Windows™ Batch File berada. Selanjutnya, command prompt mengeksekusi perintah yang memanggil GCC secara berurutan hingga berhenti akibat adanya perintah pause. Untuk melanjutkan eksekusi, kita cukup menekan sebarang tombol pada keyboard sehingga command prompt mengeksekusi perintah selanjutnya yaitu Object Dump.
EAX, EBX, ECX, dan EDX adalah register 32-bit yang bersifat general storage. ESI dan EDI adalah register 32-bit yang digunakan sebagai indexing register. Register ini juga dapat digunakan sebagai general storage. ESP adalah register 32-bit yang digunakan sebagai stack pointer. Dengan demikian, ESP akan berisi nilai alamat (address) elemen puncak (top element) dari stack. Perlu diingat bahwa stack membesar dari alamat tinggi (high address) ke arah alamat rendah (low address). Dengan demikian, memasukkan elemen baru ke dalam stack akan mengurangi nilai alamat yang tersimpan pada ESP sedangkan mengeluarkan elemen dari dalam stack akan menambah ESP. EBP adalah register 32-bit yang digunakan sebagai base pointer. Dengan demikian, EBP akan berisi alamat dari current activation frame pada stack. EIP adalah register 32-bit yang digunakan sebagai instruction pointer. Dengan demikian, EIP akan berisi alamat dari instruksi selanjutnya yang akan dieksekusi. F. Stack dan Procedure Call Stack pada umumnya disusun atas beberapa activation frame. Setiap frame memiliki sebuah base pointer yang menunjukkan alamat tertinggi (highest address) pada frame tersebut. Karena stack tumbuh dari high address menuju low address, base pointer akan menunjukkan alamat tertinggi frame tersebut. Ke tika suatu program (caller) memanggil sebuah prosedur (callee), caller akan memasukkan argumenargumen untuk memanggil callee dari argumen terakhir hingga argumen paling awal secara berurutan ke dalam stack. Selanjutnya, caller akan memasukkan return address ke dalam stack. Ke mudian, callee memasukkan alamat old base pointer milik caller ke dalam stack dan memperbarui nilai base pointer yang sesuai dengan frame callee (nilai base pointer yang baru sama dengan nilai stack pointer setelah old base pointer disimpan ke dalam stack). Kemudian callee melakukan alokasi terhadap variabel lokal dan melakukan komputasi sesuai dengan fungsi callee tersebut. Ke tika callee selesai dieksekusi, callee akan menyimpan return value pada register EAX. Kemudian, callee akan membersihkan framenya sendiri dengan mengganti alamat base pointer dengan old base
pointer yang telah disimpan pada stack. Kemudian, return address digunakan untuk melanjutkan eksekusi instruksi pada caller. III. HASIL DAN ANALISIS A. Tugas 1 :Proses Kompilasi Bahasa C Menggunakan GCC Proses kompilasi Bahasa C menggunakan GCC dimulai dengan membuat code program dalam Bahasa C maka file yang dibuat berextensi file dot c (.c). Kemudian dilakukan preprocessing untuk mengubah file code.c menjadi file code.i. Kedua file ini sam-sama bertype filetext, sehingga apabila dibuka pada Notepad++ menghasilkan code seperti pada Lampiran 1a dan 1b. Perbedaan antara kedua code tersebut terlihat pada komentar yang menjadi tidak ada / hilang pada file code.i, kemudian nilai N_LOOP yang di definisikan menjadi 500, pada file code.i nilai sudah langsung terganti. Lalu pada bagian fungsi main, code di dalam fungsi main bergeser sebesar 1 tab ke kanan. Pada kompilasi kedua dilakukan proses compiling. Pada proses ini dilakukan penerjemahan code.c (Bahasa C) menjadi code.s (Bahasa Assembly). Kedua file ini berupa filetext sehingga dapa dibuka menggunakan notepad++ (dapat dilihat pada Lampiran 1b dan 1c). code.s yang sudah dalam Bahasa assembly ini berisi instruksi-instruksi yang dapat dimengerti mesin namun sulit untuk dipahami manusia. Pada kompilasi ketiga dilakukan proses Assembler. Pada proses ini dilakukan proses penerjemahkan code.s (Bahasa assembly) menjadi code.o (file objek). Pada tahap ini, file code.o bertipe file biner (bukan filetext) sehingga apa bila dibuka dengan text editor maka akan menghasilkan tampilan karakter yang kurang dapat dimengerti sebagai berikut :
Namun saat dibuka dengan HexEdit maka tampilan akan berupa suatu pola bilangan biner (seperti pada Lampiran 1e). Perbedaannya dengan file objek adalah pada executable file ini ukurannya lebih besar dan isinya lebih banyak dikarenakan file merupakan gabungan dari semua file yang terkait, misalnya library. B. Tugas 2 : Proses Kompilasi Bahasa C Menggunakan GCC dengan Bantuan Batch File Pada tugas 2 masih menggunakan code.c yang telah dibuat pada tugas 1. Sehingga file harus dicopy terlebih dahulu ke folder tugas 2. Akan dilakukan kompilasi program code.c yang telah di-copy. Akan tetapi proses kompilasi tidak dilakukan dengan memberikan perintah satu persatu pada GCC melainkan dengan membuat suatu batch file. Batch file yang digunakan sesuai dengan instruksi pada modul yaitu sebagai berikut : %~d0 cd "%~dp0" gcc -E code.c > code.i gcc -S code.c gcc -c code.c gcc -o code.exe code.c code.exe pause
Namun apabila dibuka dengan menggunakan HexEdit, maka tampilan dengan pola tertentu dalam bentuk perintah biner (dapat dilihat pada Lampiran d). Pada kompilasi terakhir dilakukan proses Linker. Pada proses ini dilakukan proses penerjemahan code.o (file objek) menjadi file code.exe (executable file). File executable bertipe file biner, sehingga apabila dibuka menggunakan text editor (misalnya Notepad++) akan menampilkan karakter yang tidak dapat dipahami juga yaitu seperti:
File batch berisi perintah yang mampu diterjemahkan oleh command interpreter. Jadi, file tersebut memiliki cara kerja yang sama dengan command prompt hanya saya berbeda pada acara eksekusinya. Proses kompilasi yang dilakukan dengan bantuan batch file hanya membutuhkan waktu yang singkat karena kompilasi tidak dilakukan tahap demi tahap melainkan hanya perlu melakukan double click pada file batch.bat. Hasilnya diperoleh yaitu berupa file code.i, code.s, code.o, dan code.exe yang sama dengan file pada tugas 1. Kompilasi dengan batch file melalakukan operasi yang sama dengan command prompt. Namun dapat lebih praktis dikarenakan user hanya perlu melakukan eksekusi file (.bat) tanpa perlu mengetikan perintah pada command prompt setiap kali akan melakukan kompilasi. Perbandingan kedua folder seperti berikut:
Isi folder tugas 1
Isi folder tugas 2
C. Tugas 3 : Disassembly File Objek Pada tugas 3 akan dilakukan proses disassembly file objek dengan menggunakan file yang sudah ada pada tugas 2. Maka terlebih dahulu file code.o dan code.exe dari folder tugas 2 di-copy ke folder tugas 3. Pertama-tama dilakukan disassembly file code.c sehingga menghasilkan file disassembly_code_o.asm (Lampiran 2a). Kemudian dilakukan pula disassembly file code.exe dan diperoleh file disassembly_code_exe.asm (Lampiran 2b). Proses disassembly yang telah dilakukan pada kedua file (code.o dan code.exe) membuktikan bahwa suatu file binary dapat diubah kembali menjadi bentuk assembly-nya. Namun terdapat perbedaan pada kedua file assembly tersebut, yaitu pada file assembly code.o hanya terdapat bagian main dari program, sedangkan pada file assembly code.exe tidak hanya terdapat main program tetapi juga disertain library program serta file-file lain pendukung program. Hal ini yang menyebabkan disassembly_code_exe.asm memiliki ukuran file yang jauh lebih besar dibandingkan dengan disassembly_code_o.asm seperti gambar berikut:
D. Tugas 4: Optimisasi Kompilasi Program pada GCC
Pada tugas 4 yang akan dilihat adalah optimisasi kompilasi program pada GCC dengan menggunakan file code.c pada tugas 2 yang di-copy dan digandakan mejadi 5 file pada folder tugas 4 dengan masing-masing nama yaitu code_O1.c, code_O2.c, code_O3.c, code_Os.c, dan code_Ofast.c. Kemudian dilakukan kompilasi kelima file kode tersebut dengan pilihan optimisasi yang berbeda lalu secara otomatis melakukan proses disassembly kelima file objek yang dihasilkan. Adapun batch file pada tugas 4 yaitu seperti berikut:
%~d0 cd "%~dp0" gcc -O0 -c gcc -O1 -c gcc -O2 -c gcc -O3 -c gcc -Os -c gcc -Ofast objdump -d objdump -d objdump -d objdump -d objdump -d objdump -d pause
code_O0.c code_O1.c code_O2.c code_O3.c code_Os.c -c code_Ofast.c code_O0.o > code_O0.s code_O1.o > code_O1.s code_O2.o > code_O2.s code_O3.o > code_O3.s code_Os.o > code_Os.s code_Ofast.o > code_Ofast.s
Pada file original tanpa optimasi (code_O0.s) menghasilkan file assembly terpanjang dibandingkan dengan file lainnnya yaitu dengan jumlah baris sebanyak 29 baris. Pada optimasi –O1, terlihat bahwa jumlah baris yang dihasilkan (19 baris) menjadi lebih sedikit daripada file code tanpa optimasi (code_O0.s). Hal ini telah sesuai dengan landasan teori yang menyatakan bahwa optimasi dengan –O1 lebih optimal untuk mengecilkan ukuran file. Pada optimasi dengan –O2, -O3, -Os, dan –Ofast memiliki jumlah baris yang sama yaitu 16 baris. Pada masingmasing optimasi (–O2, -O3, -Os, dan –Ofast) telah dilakukan pengaktifan flag yang berbeda-beda, namun dikarenakan hasil optimasi yang diperoleh sama maka dapat dikatakan bahwa optimasi dengan –O2 saja sudah cukup optimal untuk optimasi pajang file sehingga flag-flag tambahan tidak terlalu berpengaruh. Selain dituinjau dari ukuran file, proses optimasi juga dapat diamati dari segi runtime program. Pada optimasi –O2, O3, dan –Ofast kemungkinan terdapat perbedaan runtime namun karena tidak dilakukannya pengujian pada praktikum ini, maka tidak dapat dikertahui perbedaan antar optimasi dari segi runtime program. Runtime program sendiri dapat dilakukan dengan mencatat timestamp dari tiap proses yang dilakukan dengan bantuan library tambahan sehingga dapat mengakses informasi waktu dati system operasi. Ke 5 file setelah dibuka dengan teks editor dapat dilihat pada lampiran 3. E. Tugas 5: Kompilasi Beberapa File Kode dengan GCC Pada tugas 5 akan dilakukan proses kompilasi beberapa file kode dengan GCC. Maka terlebih dahulu membuat file main_text.c dan file text.c yang terlampir pada lampiran 4a dan 4b. Untuk melakukan kompilasi kedua file, maka dibutuhkan file header yang berfungsi untuk menghubungkan file main_text.c dan text.c . File header ini memuat deklarasi fungsi test pada text.c yang selanjutnya akan diterjemahkan dan digunakan pada file main_text.c. Isi dari file header yaitu text.h terlampir pada lampiran 4c. Hasil kompilasi file main_text.c dan file text.c untuk menghasilkan main_text.exe yang kemudian dijalankan yang ditampilkan pada command prompt sebagai berikut:
Program berjalan sudah sebaimana mestinya proses penjumlahan (accumlator). Maka dapat dikatakan bahwa integrase file add.c, main.c dan add.h (sebagai header file) telah berhasil. Hasil eksekusi file menunjukan bahwa GCC juga dapat digunakan untuk melakukan kompilasi beberapa file sekaligus serta menjadi penghubung antar file (dengan header) hingga menjadi satu program yang utuh.
F. Tugas 6: Penggunaan Makefile pada GCC Pada tugas 6 akan dilakukan penggunaan Makefile pada GCC dengan menggunakan file yang sudah ada sebelumnya pada tugas 5 yaitu file main_text.c, text.c dan text.h, maka semua file di-copy terlebih dahulu ke folder tugas 6. Kemudian dilakukan kompilasi kedua file tersebut dengan memanfaatkan metode makefile. Perintah untuk makefile adalah sebagai berikut : all: main_text.exe main_text.exe: main_text.o text.o gcc main_text.o text.o –o main_text.exe main_text.o: main_text.c gcc -c main_text.c
H. Tugas 8: Pemanggilan Prosedur dan Stack Memory Pada tugas 8 dilakukan proses pemanggilan prosedur dan stack memory untuk lebih memahami pemanggilan prosedur dan stack pada memory. Isi kode file main.c yang digunakan adalah kode pada isi file tugas pendahuluan (sumofquare.c). Pada proses pemanggilan prosedur, memory dapat dimodelkan sebagai stack. Hal ini karena proses pemanggilan memory tersebut berbasis stacking data. Proses kompilasi Bahasa C dilakukan secara berurutan yang mengakibatkan proses penyimpanan dan pengeluaran datanya pun dilakukan secara berurutan. Memory computer yang digunakan sifatnya dinamis, dimana ukurannya dapat membesar atau mengecil sesuai kebutuhan. Hal ini dipengaruhi oleh banyaknya data dan optimasi yang dilakukan. Memory akan dihapus setelah dilakukan pengembalian return address. Berikut nilai memory di antara addres yang ditunjukkan oleh EBP dan ESP pada setiap kode yang diinstruksikan. return squaresum(a,b);
text.o: text.c gcc -c text.c
Setelah dilakukan eksekusi dengan command prompt, diperoleh hasil kompilasi yang sama seperti hasil kompilasi pada tugas 5. Sehingga dapat disimpulkan bahwa makefile merupakan cara lain melakukan kompilasi yang praktis selain menggunakan batch file. Hasil kompilasi adalah sebagai berikut:
Nilai memory
int temp1 = square(y);
Nilai memory G. Tugas 7: Header File Pada tugas 7 akan belajar untuk membuat dan memanfaatkan header file dan memahami bagaimana extern pada header file bekerja. Untuk memulai tugas 7 maka dibuat file add.c, header file add.h yang akan di-include pada main.c dan file main.c yang meminta pengguna memasukkan dua buah bilangan lalu menjumlahkan kedua bilangan tersebut dengan memanggil fungsi sum. Masing-masing isi file terlampir pada lampiran 5a-5d. Proses pemanggilan fungsi yang telah didefinisikan pada add.c akan mengalami masalah apabila variabel accum (pada add.c) tidak di-extern terlebih dahulu sehingga variabel tidak terdefinisi pada main.c Fungsi extern pada header yaitu agar suatu variabel dalam sebuah file dapat digunakan pada file “.c” lainnya. Berikut perintah eksekusi program:
return x*x;
Nilai memory
int temp2 = square(z);
Nilai memory
return x*x;
Nilai memory
IV. SIMPULAN
return temp1+temp2;
Nilai memory I. Tugas 9: Program Fibonacci Pada tugas 9 akan dibuat program penghitung deret Fibonacci yang sederhana untuk menampilkan deret Fibonacci. Untuk membuat sebuah program penghitung deret Fibonacci yang sederhana dibutuhkan prosedur ataupun kode yaitu fibo.c, fibo.h, inputn.c, inputn.h, dan fibo_main.c, yang terlampir pada lampiran 6a-6c. Adapun kode untuk header yaitu:
Fibo.h
Inputn.h
Fibo.c adalahh file yang berisi code untuk menampilkan deret bilangan Fibonacci sebanyak n input yang dimasukan oleh user. Input diperoleh dari fungsi inputn.c . Sedangkan file fibo_main.c adalah main program yang akan memanggil kedua fungsi tersebut (fibo.c serta inputn.c). Header fibo.h berisi deklarasi untuk fungsi fibo sedangkan header inputn.h berisi deklarasi untuk fungsi inputn.h . Kedua header ini akan di-include pada fibo_main.c kedua fungsi (fibo.c serta inputn.c) dapat digunakan pada main program. Eksekusi program yaitu sebagai berikut:
Kompilasi pada GCC terdiri dari 4 tahap yaitu preprocessing, compiling, assembling, dan linking. File hasil preprocessing yaitu berekstensi “.i “. File hasil compiling berekstensi file “.s”. File hasil ssembling berekstensi file “.o” serta file hasil proses linking berekstensi “.exe” . File .o dan .exe bertype file biner sedangkan ketiga ekstensi file lainnya bertype file text. Proses kompilasi pada GCC dapat dilakukan dengan beberapa metode, yaitu menuliskan perintah tahap pertahap pada command prompt, batch file, dan juga makefile. Metode batch file pada dasarnya sama seperti melakukan compiling satu per satu, namun ditulis dalam satu file sehingga hanya memerlukan sedikit langkah pengerjaan. Sedangkan metode kompilasi dengan makefile membuat perintah eksekusi file menjadi lebih mudah. Compiler GCC dapat melakukan disassembly file objek dan file executable yaitu dengan mengubah file.o dan file.exe manjadi bertype file assembly. Kompilasi pada GCC dapat dilakukan dengan beberapa jenis optimasi (disesuaikan dengan kebutuhan), seperti –O0, -O1,-O2, -O3, -Os, dan –Ofast. Trade off yang dipertimbangkan yaitu ukuran source code, runtime program, kecepatan kompilasi, serta kemudahan dalam debugging. Header file berfungsi sebagai penghubung antara dua file atau lebih sehingga fungsi atau prosedur pada suatu fungsi juga dapat digunakan pada fungsi lain (yang dihubungkan). Extern berfungsi untuk mendeklarasikan sebuah variable global agar dapat dipakai pada semua file yang telah diubungkan dengan header. Pemanggilan prosedur dapat direpresentasikan sebagai stack memory yang bersifat dinamis (ukuran dapat membesar dan mengecil sesuai kebutuhan program yang dijalankan).
REFERENSI [1] Bryant, Randal, dan David O’Hallaron. Computer Systems : A Programmer’s Perspective 2nd Edition. 2011. Massachusetts : Pearson Education Inc. Patterson, [2] David, dan John Hennessy. Computer Organization and Design : The Hardware/Software Interface. 2012. Waltham : Elsevier Inc.
Lampiran 1. Source code untuk tugas I a. code.c // Praktikum NWS3103 Arsitektur Sistem Komputer // Modul :1 // Percobaan :1 // Tanggal : 26 September 2016 // Kelompok :5 // Rombongan :1 // Nama (NIM) 1 : Aldo Erwin Manurung (14S14022) // Nama (NIM) 2 : Grace La Rosa Sihotang (14S14010) // Nama File : code.c // Deskripsi : Demonstrasi proses kompilasi C // Menjumlahkan deret bilangan sebanyak N_LOOP #define N_LOOP 500 int main(void) { int indeks; int accumulator; indeks = 0; accumulator = 0; while(indeks" # 1 "" # 1 "code.c" # 14 "code.c" int main(void) { int indeks; int accumulator; indeks = 0; accumulator = 0; while(indeks<500) { accumulator = accumulator + indeks; indeks = indeks + 1; } return accumulator; } c. code.s .file .def .text .globl _main .def _main: pushl movl
"code.c" ___main;
.scl
2;
.type
32;
_main; .scl
2;
.type
32;
.endef
%ebp %esp, %ebp
.endef
subl andl movl movl movl call call movl movl
$24, %esp $-16, %esp $0, %eax %eax, -12(%ebp) -12(%ebp), %eax __alloca ___main $0, -4(%ebp) $0, -8(%ebp)
cmpl jle jmp
$499, -4(%ebp) L4 L3
movl leal addl leal incl jmp
-4(%ebp), %eax -8(%ebp), %edx %eax, (%edx) -4(%ebp), %eax (%eax) L2
movl leave ret
-8(%ebp), %eax
L2:
L4:
L3:
d. code.o
e. code.exe
2. Hasil tugas 3 a. Disasssembly_code_o.asm code.o: file format pe-i386 Disassembly of section .text: 00000000 <_main>: 0:55 push %ebp 1:89 e5 mov %esp,%ebp 3:83 e4 f0 and $0xfffffff0,%esp 6:83 ec 10 sub $0x10,%esp 9:e8 00 00 00 00 call e <_main+0xe> e:c7 44 24 0c 00 00 00 movl $0x0,0xc(%esp) 15:00 16:c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) 1d:00 1e:eb 0c jmp 2c <_main+0x2c> 20:8b 44 24 0c mov 0xc(%esp),%eax 24:01 44 24 08 add %eax,0x8(%esp) 28:ff 44 24 0c incl 0xc(%esp) 2c:81 7c 24 0c f3 01 00 cmpl $0x1f3,0xc(%esp)
33:00 34:7e 36:8b 3a:c9 3b:c3
b.
3.
ea jle 20 <_main+0x20> 44 24 08 mov 0x8(%esp),%eax leave ret
Disassembly_code_exe.asm (hanya sebagian screen shoot code
Hasil tugas 4 a. Code_O0.s code_O0.o: file format pe-i386 Disassembly of section .text: 00000000 <_main>: 0:55 push %ebp 1:89 e5 mov %esp,%ebp 3:83 e4 f0 and $0xfffffff0,%esp 6:83 ec 10 sub $0x10,%esp 9:e8 00 00 00 00 call e <_main+0xe> e:c7 44 24 0c 00 00 00 movl $0x0,0xc(%esp)
15:00 16:c7 1d:00 1e:eb 20:8b 24:01 28:ff 2c:81 33:00 34:7e 36:8b 3a:c9 3b:c3
b.
44 24 08 00 00 00 movl $0x0,0x8(%esp) 0c 44 44 44 7c
jmp 2c <_main+0x2c> 24 0c mov 0xc(%esp),%eax 24 08 add %eax,0x8(%esp) 24 0c incl 0xc(%esp) 24 0c f3 01 00 cmpl $0x1f3,0xc(%esp)
ea jle 20 <_main+0x20> 44 24 08 mov 0x8(%esp),%eax leave ret
Code_O1.s code_O1.o: file format pe-i386 Disassembly of section .text: 00000000 <_main>: 0:55 push %ebp 1:89 e5 mov %esp,%ebp 3:83 e4 f0 and $0xfffffff0,%esp 6:e8 00 00 00 00 call b <_main+0xb> b:b8 00 00 00 00 mov $0x0,%eax 10:40 inc %eax 11:3d f4 01 00 00 cmp $0x1f4,%eax 16:75 f8 jne 10 <_main+0x10> 18:b8 4e e7 01 00 mov $0x1e74e,%eax 1d:c9 leave 1e:c3 ret 1f:90 nop
c.
Code_O2.s code_O2.o: file format pe-i386 Disassembly of section .text.startup: 00000000 <_main>: 0:55 push %ebp 1:89 e5 mov %esp,%ebp 3:83 e4 f0 and $0xfffffff0,%esp 6:e8 00 00 00 00 call b <_main+0xb> b:b8 4e e7 01 00 mov $0x1e74e,%eax 10:c9 leave 11:c3 ret 12:90 nop 13:90 nop
d.
Code_O3.s code_O3.o: file format pe-i386 Disassembly of section .text.startup: 00000000 <_main>: 0:55 push %ebp 1:89 e5 mov %esp,%ebp 3:83 e4 f0 and $0xfffffff0,%esp 6:e8 00 00 00 00 call b <_main+0xb> b:b8 4e e7 01 00 mov $0x1e74e,%eax 10:c9 leave 11:c3 ret 12:90 nop 13:90 nop
e.
Code_Os.s code_Os.o: file format pe-i386 Disassembly of section .text.startup: 00000000 <_main>: 0:55 push %ebp 1:89 e5 mov %esp,%ebp 3:83 e4 f0 and $0xfffffff0,%esp
6:e8 00 00 00 00 call b <_main+0xb> b:b8 4e e7 01 00 mov $0x1e74e,%eax 10:c9 leave 11:c3 ret 12:90 nop 13:90 nop
f.
Code_Ofast.s code_Ofast.o: file format pe-i386 Disassembly of section .text.startup: 00000000 <_main>: 0:55 push %ebp 1:89 e5 mov %esp,%ebp 3:83 e4 f0 and $0xfffffff0,%esp 6:e8 00 00 00 00 call b <_main+0xb> b:b8 4e e7 01 00 mov $0x1e74e,%eax 10:c9 leave 11:c3 ret 12:90 nop 13:90 nop
4.
Hasil Tugas 5 a. Main_text.c // Praktikum NWS3103 Arsitektur Sistem Komputer // Modul : 1 // Percobaan : 5 // Tanggal : 26 September 2016 // Kelompok : 5 // Rombongan : 1 // Nama (NIM) 1 : Aldo Erwin Manurung (14S14022) // Nama (NIM) 2 : Grace La Rosa Sihotang(14S14022) // Nama File : main_text.c // Deskripsi : Demonstrasi MakeFile // Memanggil prosedur test pada text.c #include "text.h" void main(void) { test(); }
b.
Text.c // Praktikum NWS3103 Arsitektur Sistem Komputer // Modul : 1 // Percobaan : 5 // Tanggal : 26 September 2016 // Kelompok : 5 // Rombongan : 1 // Nama (NIM) 1 : Aldo Erwin Manurung (14S14022) // Nama (NIM) 2 : Grace La Rosa Sihotang(14S14022) // Nama File : text.c // Deskripsi : Demonstrasi MakeFile, Mencetak string ke layar #include #include "text.h" void test(void) { printf("Arsitektur Sistem Komputer sangat menyenangkan!\n"); }
c.
Text.h #ifndef TES_H #define TES_H 100 void test(void); #endif
5.
Hasil Tugas 7 a. Add.c // Praktikum NWS3103 Arsitektur Sistem Komputer // Modul : 1 // Percobaan : 7 // Tanggal : 26 September 2016 // Kelompok : 5 // Rombongan : 1 // Nama (NIM) 1 : Aldo Erwin Manurung (14S14022) // Nama (NIM) 2 : Grace La Rosa Sihotang(14S14022) // Nama File : add.c // Deskripsi : Demonstrasi header file // Menjumlahkan dua bilangan #define START_VAL 0 int accum = START_VAL; int sum(int x, int y) { int t = x + y; accum += t; return t; }
b.
Main.c // Praktikum NWS3103 Arsitektur Sistem Komputer // Modul : 1 // Percobaan : 7 // Tanggal : 26 September 2016 // Kelompok : 5 // Rombongan : 1 // Nama (NIM) 1 : Aldo Erwin Manurung (14S14022) // Nama (NIM) 2 : Grace La Rosa Sihotang(14S14022) // Nama File : main.c // Deskripsi : Demonstrasi header file // Menjumlahkan dua bilangan #include #include "add.h" int main(void) { int x,y,z; scanf("%d", &x); scanf("%d", &y); z = sum(x,y); printf("%d", z); return 0; }
c.
Add.h #ifndef accum extern int sum (int x, int y); #endif
d.
Makefile all: main.exe main.exe: main.o add.o gcc main.o add.o -o main.exe main.o: main.c gcc -c main.c add.o: add.c gcc -c add.c
6.
Kode program untuk tugas 9 a. Inputn.c // Praktikum NWS3103 Arsitektur Sistem Komputer // Modul : 1 // Percobaan : 9 // Tanggal : 26 September 2016 // Kelompok : 5 // Rombongan : 1 // Nama (NIM) 1 : Aldo Erwin Manurung (14S14022) // Nama (NIM) 2 : Grace La Rosa Sihotang(14S14022) // Nama File : inputn.c // Deskripsi : Program fibonacci #include #define START_VAL 0 int accum = START_VAL; int input (void) { int n; scanf("%d", &n); while (n<2) { scanf("%d", &n); } return (n); }
b.
Fibo.c // Praktikum NWS3103 Arsitektur Sistem Komputer // Modul : 1 // Percobaan : 9 // Tanggal : 26 September 2016 // Kelompok : 5 // Rombongan : 1 // Nama (NIM) 1 : Aldo Erwin Manurung (14S14022) // Nama (NIM) 2 : Grace La Rosa Sihotang(14S14022) // Nama File : fibo.c // Deskripsi : Program fibonacci #include int fibo (int n) { int i; int a = 1; int b = 1; int c; printf("1, 1, "); for (i=1;i<=n-2;i++) { c = a+b; printf("%d, ",c); a = b; b = c; } return 0; }
c.
Fibo_main.c // // // // // // // // //
Praktikum NWS3103 Arsitektur Sistem Komputer Modul : 1 Percobaan : 9 Tanggal : 26 September 2016 Kelompok : 5 Rombongan : 1 Nama (NIM) 1 : Aldo Erwin Manurung (14S14022) Nama (NIM) 2 : Grace La Rosa Sihotang(14S14022) Nama File : fibo_main.c
// Deskripsi : Program fibonacci #include #include "inputn.h" #include "fibo.h" int main(void) { int a; a = input(); fibo(a); return 0 ; }