I. PENDAHULUAN • Preprocessor
Semua perintah preprocessoryang ditulis dalam bahasa tingkat
D alam proses pembuatan suatu program, bahasa tingkat
tinggi lebih banyak digunakan karena bahasa tersebut
lebih mudah dimengerti dan dipahami oleh manusia seperti
tinggi akan diproses terlebih dahulu oleh preprocessor sebelum
compiler melaksanakan tugasnya. Beberapa tugas dari
preprocessor ini adalah sebagai berikut.
Bahasa C. Namun, bahasa tersebut tidak dapat dibaca oleh
o Semua komentar dalam file program diganti dengan
mesin (mikroposessor) yang berbasis bahasa tingkat rendah,
spasi satu buah.
sehingga program tersebut tidak akan di eksekusi. Oleh karena
o Semua \n (backslash-newline) yang menandakan baris
itu akan diperlukan suatu penghubung antara bahasa tingkat
baru akan dihapus tidak peduli dimanapun dia berada.
tinggi dan bahasa tingkat rendah yaitu berupa bahasa assembly
Fitur ini memungkinkan kita untuk membagi baris
yang menjadi penerjemah pemrograman tingkat tinggi
program yang panjang ke dalam beberapa baris tanpa
menjadi Bahasa tingkat rendah yang berisi urutan instruksi
mengubah arti.
yang dimengerti oleh mesin. Proses penerjemahan dari Bahasa
o Macro yang telah didefinisikan diganti dengan
tingkat tinggi menjadi Bahasa Assembly yang dimengerti
definisinya.
oleh mesin disebut compilation. Contohnya, pada perintah #define MAX_ROWS 10,
Pada praktikum ini tujuan yang ingin dicapai antara lain : preprocessor akan mengganti semua kataMAX_ROWS dengan
1. Praktikan memahami tahap-tahap kompilasi program
10.Pada perintah #include <stdio.h>, preprocessor akan
dalam bahasa C sebagai bahasa tingkat tinggi hingga
mengganti baris tersebut dengan isi file stdio.h
diperoleh bahasa tingkat rendah yang dapat
dieksekusi oleh mesin.
2. Praktikan mampu melakukan kompilasi program • Compiler
bahasa C menggunakan compiler GCC beserta Compiler akan menerjemahkan bahasa tingkat tinggi C menjadi
penggunaan makefile dan batch file. kode assembly. Kode assembly ini berisi instruksi-instruksi
3. Praktikan memahami bahasa assembly dan mampu yang sesuai dengan instruction set yang dimiliki oleh mesin.
melakukan analisis terhadap bahasa assembly Intel® File yang dihasilkan pada tahap ini masih berupa file teks (.s).
x86 yang dihasilkan oleh compiler GCC.
dua file objek bernama main.o dan text.o (tentunya termasuk
dengan library yang lain yang dibutuhkan). Untuk memperoleh
• Assembler main.o, GCC harus melakukan kompilasi source code main.c
Assembler akan menerjemahkan bahasa assembly menjadi file menjadi file objek. Begitupula untuk memperoleh text.o, GCC
objek. File objek ini merupakan file biner (.o). harus melakukan kompilasi source code text.c.
Pada platform Microsoft® Windows™, terdapat sebuah file
• Linker shell script bernama Windows™ Batch File. Kita dapat
menuliskan perintah-perintah yang biasa kita tuliskan secara
Linker akan menggabungkan file biner yang diperoleh pada
terpisah pada command prompt dalam suatu file yang disimpan
tahap sebelumnya dengan file biner lain yang merupakan
dengan ekstensi .bat. Untuk mengeksekusi perintah-perintah
dependency dari program yang dibuat, contohnya library tersebut, kita cukup menjalankan file .bat tersebut sehingga
untuk menjalankan fungsi printf. Hasil dari linker berupa file command prompt terbuka dan perintah-perintah yang kita
biner executable (dalam platform Microsoft® Windows™, tuliskan dieksekusi secara otomatis. Contoh Windows™ Batch
file ini memiliki akhiran .exe). File adalah sebagai berikut.
%~d0
A. Disassembly menggunakan GCC
cd "%~dp0"
Selain dapat melakukan kompilasi, paket compiler GCC juga gcc -E code.c > code.i
menyertakan sebuah disassembler yang mampu melakukan gcc -S code.c
disassembly file biner (.o atau .exe) menjadi file assembly (.s) gcc -c code.c
bernama Object Dump gcc -o code.exe code.c
code.exe
B. Optimasi Program melalui Proses Kompilasi
GCC mendukung beberapa tingkat optimisasi program yang pause
dapat dilakukan saat proses kompilasi dilakukan. Terdapat Gambar 4 Windows Batch file
beberapa tingkat optimisasi program yang dapat dipilih dengan
menambahkan flag optimisasi saat melakukan kompilasi
program. Umumnya optimisasi program merupakan trade-off Perintah %~d0 memerintahkan command prompt untuk
antara execution speed, program size, compilation time, dan berpindah drive letter ke drive letter yang sesuai dengan lokasi
kemudahan dalam melakukan debugging. Beberapa flag Windows™ Batch File berada. Selanjutnya, perintah cd
optimisasi yang dikenali oleh GCC adalah –O0, –O1, –O2, – "%~dp0" memerintahkan command prompt untuk berpindah
O3, –Os, dan –Ofast. folder ke lokasi Windows™ Batch File berada. Selanjutnya,
command prompt mengeksekusi perintah yang memanggil
C. Makefile dan Batch File GCC secara berurutan hingga berhenti akibat adanya perintah
GCC memiliki fitur makefile yang berfungsi untuk menulis pause. Untuk melanjutkan eksekusi, kita cukup menekan
daftar nama file kode di dalam project. Cukup memberikan sebarang tombol pada keyboard sehingga command prompt
GCC nama makefile lalu GCC akan melakukan proses mengeksekusi perintah selanjutnya yaitu Object Dump.
kompilasi untuk semua file tersebut untuk kemudian
menggabungkannya pada file executable. Makefile dapat D. Instruksi dan Bahasa Assembly Intel® x86
bersifat sederhana hingga kompleks, bergantung pada sejauh
mana kita menggunakan makefile untuk mengorganisasikan Arsitektur mikroprosesor Intel® x86 merupakan salah satu
project. Contoh isi dari makefile adalah sebagai berikut : 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 :
• EAX, EBX, ECX, dan EDX adalah register32-bit
Gambar 2 Contoh Makefile yang bersifat general storage.
Kemudian untuk melakukan kompilasi makefile diberikan • ESI dan EDIadalah register32-bit yang digunakan
perintah sebagai berikut: sebagai indexing register. Registerini juga dapat
digunakan sebagai general storage.
• ESP adalah register32-bit yang digunakan sebagai
Gambar 3 Perintah Kompilasi stack pointer. Dengan demikian, ESPakan berisi nilai
alamat (address) elemen puncak (top element) dari
Perintah tersebut akan melakukan kompilasi terhadap stack. Perlu diingat bahwa stack membesar dari alamat
makefile yang diberikan menjadi sebuah program bernama tinggi (high address) ke arah alamat rendah (low
contoh.exe. Program ini dihasilkan oleh hasil linker terhadap address). Dengan demikian, memasukkan elemen
baru ke dalam stack akan mengurangi nilai alamat Proses terakhir yaitu Linker. Proses ini berperan untuk
yangtersimpan pada ESPsedangkan mengeluarkan mengubah code.o (file objek) menjadi code.exe (executable
elemen dari dalam stack akan menambah ESP. file). File executable ini juga bertipe file biner, sehingga apabila
• EBP adalah register 32-bit yang digunakan sebagai dibuka menggunakan text editor akan menampilkan kumpulan
base pointer. Dengan demikian, EBP akan berisi karakter yang tidak dapat dipahami sebagai berikut:
alamat dari current activation frame pada stack.
• EIP adalah register 32-bit yang digunakan sebagai
instruction pointer
3. int temp2 = square(z) • Kompilasi pada GCC dapat dilakukan dengan beberapa
Call stack : function : squaresum(y-5,z=9) 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
4. return x*x memerlukan sedikit langkah pengerjaan. Sedangkan metode
Call stack : function : square(x=9) kompilasi dengan makefile membuat perintah eksekusi file
menjadi lebih mudah
7. akhir program
REFERENSI
[1] Bryant, Randal, dan David O’Hallaron. Computer Systems
: A Programmer’s Perspective 2nd Edition. Massachusett.
2011.
Lampiran
1. Source code untuk tugas I
a. Code.c
// Praktikum NWS3103 Arsitektur Sistem Komputer
// Modul : 1
// Percobaan : 1
// Tanggal : 28 September 2017
// Kelompok : 9
// Rombongan : 1
// Nama (NIM) 1 : Andri Simanjuntak (14S15003)
// Nama (NIM) 2 : Friyogi Tampubolon (14S15025)
// Nama (NIM) 3 : Adi Silaen (14S15061)
// Nama File : code.c
// Deskripsi : Demonstrasi proses kompilasi C
// Menjumlahkan deret bilangan sebanyak N_LOOP
b. file code.i
# 1 "code.c"
# 1 "<built-in>"
# 1 "<command line>"
# 1 "code.c"
# 15 "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. file code.s
.file "code.c"
.def ___main; .scl 2; .type 32; .endef
.text
.globl _main
.def _main; .scl 2; .type 32; .endef
_main:
pushl %ebp
movl %esp, %ebp
subl $24, %esp
andl $-16, %esp
movl $0, %eax
movl %eax, -12(%ebp)
movl -12(%ebp), %eax
call __alloca
call ___main
movl $0, -4(%ebp)
movl $0, -8(%ebp)
L2:
cmpl $499, -4(%ebp)
jle L4
jmp L3
L4:
movl -4(%ebp), %eax
leal -8(%ebp), %edx
addl %eax, (%edx)
leal -4(%ebp), %eax
incl (%eax)
jmp L2
L3:
movl -8(%ebp), %eax
leave
ret
d. file code.o
e. file code.exe
00000000 <_main>:
0: 55 push %ebp
1: 89 e5 mov %esp,%ebp
3: 83 ec 18 sub $0x18,%esp
6: 83 e4 f0 and $0xfffffff0,%esp
9: b8 00 00 00 00 mov $0x0,%eax
e: 89 45 f4 mov %eax,0xfffffff4(%ebp)
11: 8b 45 f4 mov 0xfffffff4(%ebp),%eax
14: e8 00 00 00 00 call 19 <_main+0x19>
19: e8 00 00 00 00 call 1e <_main+0x1e>
1e: c7 45 fc 00 00 00 00 movl $0x0,0xfffffffc(%ebp)
25: c7 45 f8 00 00 00 00 movl $0x0,0xfffffff8(%ebp)
2c: 81 7d fc f3 01 00 00 cmpl $0x1f3,0xfffffffc(%ebp)
33: 7e 02 jle 37 <_main+0x37>
35: eb 0f jmp 46 <_main+0x46>
37: 8b 45 fc mov 0xfffffffc(%ebp),%eax
3a: 8d 55 f8 lea 0xfffffff8(%ebp),%edx
3d: 01 02 add %eax,(%edx)
3f: 8d 45 fc lea 0xfffffffc(%ebp),%eax
42: ff 00 incl (%eax)
44: eb e6 jmp 2c <_main+0x2c>
46: 8b 45 f8 mov 0xfffffff8(%ebp),%eax
49: c9 leave
4a: c3 ret
4b: 90 nop
4c: 90 nop
4d: 90 nop
4e: 90 nop
4f: 90 nop
00401000 <__RUNTIME_PSEUDO_RELOC_LIST_END__>:
401000: 55 push %ebp
401001: 89 e5 mov %esp,%ebp
401003: 83 ec 28 sub $0x28,%esp
401006: c7 44 24 04 04 20 40 movl $0x402004,0x4(%esp,1)
40100d: 00
40100e: 8d 45 fc lea 0xfffffffc(%ebp),%eax
401011: 89 44 24 10 mov %eax,0x10(%esp,1)
401015: a1 10 20 40 00 mov 0x402010,%eax
40101a: c7 45 fc 00 00 00 00 movl $0x0,0xfffffffc(%ebp)
401021: c7 04 24 00 20 40 00 movl $0x402000,(%esp,1)
401028: 89 44 24 0c mov %eax,0xc(%esp,1)
40102c: 8d 45 f8 lea 0xfffffff8(%ebp),%eax
40102f: 89 44 24 08 mov %eax,0x8(%esp,1)
401033: e8 b8 07 00 00 call 4017f0 <___getmainargs>
401038: 89 ec mov %ebp,%esp
40103a: 5d pop %ebp
40103b: c3 ret
40103c: 8d 74 26 00 lea 0x0(%esi,1),%esi
00401040 <__mingw32_init_fmode>:
401040: 55 push %ebp
401041: 89 e5 mov %esp,%ebp
401043: 83 ec 08 sub $0x8,%esp
401046: a1 20 20 40 00 mov 0x402020,%eax
40104b: 85 c0 test %eax,%eax
40104d: 74 57 je 4010a6 <__mingw32_init_fmode+0x66>
40104f: a3 30 20 40 00 mov %eax,0x402030
401054: a1 d0 40 40 00 mov 0x4040d0,%eax
401059: 85 c0 test %eax,%eax
40105b: 75 5a jne 4010b7 <__mingw32_init_fmode+0x77>
40105d: 83 f8 e0 cmp $0xffffffe0,%eax
401060: 74 22 je 401084 <__mingw32_init_fmode+0x44>
3. Source code untuk Tugas 4
a. code_O0.s
00000000 <_main>:
0: 55 push %ebp
1: 89 e5 mov %esp,%ebp
3: 83 ec 18 sub $0x18,%esp
6: 83 e4 f0 and $0xfffffff0,%esp
9: b8 00 00 00 00 mov $0x0,%eax
e: 89 45 f4 mov %eax,0xfffffff4(%ebp)
11: 8b 45 f4 mov 0xfffffff4(%ebp),%eax
14: e8 00 00 00 00 call 19 <_main+0x19>
19: e8 00 00 00 00 call 1e <_main+0x1e>
1e: c7 45 fc 00 00 00 00 movl $0x0,0xfffffffc(%ebp)
25: c7 45 f8 00 00 00 00 movl $0x0,0xfffffff8(%ebp)
2c: 81 7d fc f3 01 00 00 cmpl $0x1f3,0xfffffffc(%ebp)
33: 7e 02 jle 37 <_main+0x37>
35: eb 0f jmp 46 <_main+0x46>
37: 8b 45 fc mov 0xfffffffc(%ebp),%eax
3a: 8d 55 f8 lea 0xfffffff8(%ebp),%edx
3d: 01 02 add %eax,(%edx)
3f: 8d 45 fc lea 0xfffffffc(%ebp),%eax
42: ff 00 incl (%eax)
44: eb e6 jmp 2c <_main+0x2c>
46: 8b 45 f8 mov 0xfffffff8(%ebp),%eax
49: c9 leave
4a: c3 ret
4b: 90 nop
4c: 90 nop
4d: 90 nop
4e: 90 nop
4f: 90 nop
b. code_O1.s
00000000 <_main>:
0: 55 push %ebp
1: 89 e5 mov %esp,%ebp
3: 83 ec 08 sub $0x8,%esp
6: 83 e4 f0 and $0xfffffff0,%esp
9: b8 00 00 00 00 mov $0x0,%eax
e: e8 00 00 00 00 call 13 <_main+0x13>
13: e8 00 00 00 00 call 18 <_main+0x18>
18: ba 00 00 00 00 mov $0x0,%edx
1d: b8 00 00 00 00 mov $0x0,%eax
22: 01 d0 add %edx,%eax
24: 42 inc %edx
25: 81 fa f3 01 00 00 cmp $0x1f3,%edx
2b: 7e f5 jle 22 <_main+0x22>
2d: c9 leave
2e: c3 ret
2f: 90 nop
c. code_O2.s
00000000 <_main>:
0: 55 push %ebp
1: 89 e5 mov %esp,%ebp
3: 50 push %eax
4: 50 push %eax
5: 31 c0 xor %eax,%eax
7: 83 e4 f0 and $0xfffffff0,%esp
a: e8 00 00 00 00 call f <_main+0xf>
f: e8 00 00 00 00 call 14 <_main+0x14>
14: 31 c0 xor %eax,%eax
16: 31 d2 xor %edx,%edx
18: 01 d0 add %edx,%eax
1a: 42 inc %edx
1b: 81 fa f3 01 00 00 cmp $0x1f3,%edx
21: 7e f5 jle 18 <_main+0x18>
23: c9 leave
24: c3 ret
25: 90 nop
26: 90 nop
27: 90 nop
28: 90 nop
29: 90 nop
2a: 90 nop
2b: 90 nop
2c: 90 nop
2d: 90 nop
2e: 90 nop
2f: 90 nop
d. code_O3.s
00000000 <_main>:
0: 55 push %ebp
1: 89 e5 mov %esp,%ebp
3: 50 push %eax
4: 50 push %eax
5: 31 c0 xor %eax,%eax
7: 83 e4 f0 and $0xfffffff0,%esp
a: e8 00 00 00 00 call f <_main+0xf>
f: e8 00 00 00 00 call 14 <_main+0x14>
14: 31 c0 xor %eax,%eax
16: 31 d2 xor %edx,%edx
18: 01 d0 add %edx,%eax
1a: 42 inc %edx
1b: 81 fa f3 01 00 00 cmp $0x1f3,%edx
21: 7e f5 jle 18 <_main+0x18>
23: c9 leave
24: c3 ret
25: 90 nop
26: 90 nop
27: 90 nop
28: 90 nop
29: 90 nop
2a: 90 nop
2b: 90 nop
2c: 90 nop
2d: 90 nop
2e: 90 nop
2f: 90 nop
e. code_Os.s
00000000 <_main>:
0: 55 push %ebp
1: 89 e5 mov %esp,%ebp
3: e8 00 00 00 00 call 8 <_main+0x8>
8: 31 c0 xor %eax,%eax
a: 31 d2 xor %edx,%edx
c: 01 d0 add %edx,%eax
e: 42 inc %edx
f: 81 fa f3 01 00 00 cmp $0x1f3,%edx
15: 7e f5 jle c <_main+0xc>
17: 5d pop %ebp
18: c3 ret
19: 90 nop
1a: 90 nop
1b: 90 nop
1c: 90 nop
1d: 90 nop
1e: 90 nop
1f: 90 nop
f. code_Ofast.s
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: 31 c0 xor %eax,%eax
d: 31 d2 xor %edx,%edx
f: 90 nop
10: 01 d0 add %edx,%eax
12: 83 c2 01 add $0x1,%edx
15: 81 fa f4 01 00 00 cmp $0x1f4,%edx
1b: 75 f3 jne 10 <_main+0x10>
1d: c9 leave
1e: c3 ret
1f: 90 nop
b. Text.c
// Praktikum NWS3103 Arsitektur Sistem Komputer
// Modul : 1
// Percobaan : 5
// Tanggal : 28 September 2017
// Kelompok : 9
// Rombongan : 1
// Nama (NIM) 1 : Andri Simanjuntak (14S15003)
// Nama (NIM) 2 : Friyogi Tampubolon (14S15025)
// Nama (NIM) 3 : Adi Silaen (14S15061)
// Nama File : text.c
// Deskripsi : Demonstrasi MakeFile, Mencetak string ke layar
#include <stdio.h>
#include "text.h"
void test(void)
{
printf("Arsitektur Sistem Komputer sangat menyenangkan!\n");
}
c. Text.h
// Praktikum NWS3103 Arsitektur Sistem Komputer
// Modul : 1
// Percobaan : 5
// Tanggal : 28 September 2017
// Kelompok : 9
// Rombongan : 1
// Nama (NIM) 1 : Andri Simanjuntak (14S15003)
// Nama (NIM) 2 : Friyogi Tampubolon (14S15025)
// Nama (NIM) 3 : Adi Silaen (14S15061)
// Nama File : text.h
// Deskripsi : Demonstrasi MakeFile, Mencetak string ke layar
#ifndef TES_H
#define TES_H 100
void test(void);
#endif
b. Main.c
// Praktikum NWS3103 Arsitektur Sistem Komputer
// Modul : 1
// Percobaan : 7
// Tanggal : 28 September 2017
// Kelompok : 9
// Rombongan : 1
// Nama (NIM) 1 : Andri Simanjuntak (14S15003)
// Nama (NIM) 2 : Friyogi Tampubolon (14S15025)
// Nama (NIM) 3 : Adi Silaen (14S15061)
// Nama File : main.c
// Deskripsi : Demonstrasi header file
// Menjumlahkan dua bilangan
#include<stdio.h>
#include"add.h"
int x , y;
int main()
{
printf("Masukkan nilai x : \n");
scanf("%d",&x);
printf("Masukkan nilai y : \n");
scanf("%d",&y);
int z = sum(x,y);
printf("\n%d",z);
}
c. Add.h
// Praktikum NWS3103 Arsitektur Sistem Komputer
// Modul : 1
// Percobaan : 7
// Tanggal : 28 September 2017
// Kelompok : 9
// Rombongan : 1
// Nama (NIM) 1 : Andri Simanjuntak (14S15003)
// Nama (NIM) 2 : Friyogi Tampubolon (14S15025)
// Nama (NIM) 3 : Adi Silaen (14S15061)
// Nama File : add.h
// Deskripsi : Demonstrasi header file
// Menjumlahkan dua bilangan
#ifndef ADD_H
#define ADD_H
int sum(int x, int y);
#endif
#include <stdio.h>
b. Fibo_main.c
// Praktikum NWS3103 Arsitektur Sistem Komputer
// Modul : 1
// Percobaan : 9
// Tanggal : 28 September 2017
// Kelompok : 9
// Rombongan : 1
// Nama (NIM) 1 : Andri Simanjuntak (14S15003)
// Nama (NIM) 2 : Friyogi Tampubolon (14S15025)
// Nama (NIM) 3 : Adi Silaen (14S15061)
// Nama File : fibo_main.c
// Deskripsi : program fibonacci
#include <stdio.h>
#include "inputn.h"
#include "fibo.h"
int main(void)
{
int a;
a = input();
fibo(a);
return 0 ;
}
c. Inputn.c
// Praktikum NWS3103 Arsitektur Sistem Komputer
// Modul : 1
// Percobaan : 9
// Tanggal : 28 September 2017
// Kelompok : 9
// Rombongan : 1
// Nama (NIM) 1 : Andri Simanjuntak (14S15003)
// Nama (NIM) 2 : Friyogi Tampubolon (14S15025)
// Nama (NIM) 3 : Adi Silaen (14S15061)
// Nama File : inputn.c
// Deskripsi : program fibonacci
#include <stdio.h>
#define START_VAL 0
}
return (n);
}
d. Fibo.h
// Praktikum NWS3103 Arsitektur Sistem Komputer
// Modul : 1
// Percobaan : 9
// Tanggal : 28 September 2017
// Kelompok : 9
// Rombongan : 1
// Nama (NIM) 1 : Andri Simanjuntak (14S15003)
// Nama (NIM) 2 : Friyogi Tampubolon (14S15025)
// Nama (NIM) 3 : Adi Silaen (14S15061)
// Nama File : fibo.h
// Deskripsi : program fibonacci
#ifdef accum
extern int fibo (int n);
#endif
e. Inputn.h
// Praktikum NWS3103 Arsitektur Sistem Komputer
// Modul : 1
// Percobaan : 9
// Tanggal : 28 September 2017
// Kelompok : 9
// Rombongan : 1
// Nama (NIM) 1 : Andri Simanjuntak (14S15003)
// Nama (NIM) 1 : Friyogi Tampubolon (14S15025)
// Nama (NIM) 2 : Adi Silaen (14S15061)
// Nama File : inputn.h
// Deskripsi : program fibonacci
#ifdef accum
extern int
input;
#endif