================================================================================== 1. Compiling normally with -v (verbose) switch ================================================================================== cis-lclient19:~/2012/sys2>more hello.c #include main () { printf("Hello world\n"); } cis-lclient19:~/2012/sys2>gcc -v hello.c Using built-in specs. Target: i686-redhat-linux Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre --enable-libgcj-multifile --enable-java-maintainer-mode --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --disable-libjava-multilib --with-ppl --with-cloog --with-tune=generic --with-arch=i686 --build=i686-redhat-linux Thread model: posix gcc version 4.4.5 20101112 (Red Hat 4.4.5-2) (GCC) COLLECT_GCC_OPTIONS='-v' '-mtune=generic' '-march=i686' /usr/libexec/gcc/i686-redhat-linux/4.4.5/cc1 -quiet -v hello.c -quiet -dumpbase hello.c -mtune=generic -march=i686 -auxbase hello -version -o /tmp/ccIGFgFJ.s ignoring nonexistent directory "/usr/lib/gcc/i686-redhat-linux/4.4.5/include-fixed" ignoring nonexistent directory "/usr/lib/gcc/i686-redhat-linux/4.4.5/../../../../i686-redhat-linux/include" #include "..." search starts here: #include <...> search starts here: /usr/local/include /usr/lib/gcc/i686-redhat-linux/4.4.5/include /usr/include End of search list. GNU C (GCC) version 4.4.5 20101112 (Red Hat 4.4.5-2) (i686-redhat-linux) compiled by GNU C version 4.4.5 20101112 (Red Hat 4.4.5-2), GMP version 4.3.1, MPFR version 2.4.2. GGC heuristics: --param ggc-min-expand=98 --param ggc-min-heapsize=128288 Compiler executable checksum: e892644090a9a7e8c330a388c51818dd COLLECT_GCC_OPTIONS='-v' '-mtune=generic' '-march=i686' as -V -Qy -o /tmp/ccwKgwC9.o /tmp/ccIGFgFJ.s GNU assembler version 2.20.51.0.2 (i686-redhat-linux) using BFD version version 2.20.51.0.2-20.fc13 20091009 COMPILER_PATH=/usr/libexec/gcc/i686-redhat-linux/4.4.5/:/usr/libexec/gcc/i686-redhat-linux/4.4.5/:/usr/libexec/gcc/i686-redhat-linux/:/usr/lib/gcc/i686-redhat-linux/4.4.5/:/usr/lib/gcc/i686-redhat-linux/:/usr/libexec/gcc/i686-redhat-linux/4.4.5/:/usr/libexec/gcc/i686-redhat-linux/:/usr/lib/gcc/i686-redhat-linux/4.4.5/:/usr/lib/gcc/i686-redhat-linux/ LIBRARY_PATH=/usr/lib/gcc/i686-redhat-linux/4.4.5/:/usr/lib/gcc/i686-redhat-linux/4.4.5/:/usr/lib/gcc/i686-redhat-linux/4.4.5/../../../:/lib/:/usr/lib/ COLLECT_GCC_OPTIONS='-v' '-mtune=generic' '-march=i686' /usr/libexec/gcc/i686-redhat-linux/4.4.5/collect2 --no-add-needed --eh-frame-hdr --build-id -m elf_i386 --hash-style=gnu -dynamic-linker /lib/ld-linux.so.2 /usr/lib/gcc/i686-redhat-linux/4.4.5/../../../crt1.o /usr/lib/gcc/i686-redhat-linux/4.4.5/../../../crti.o /usr/lib/gcc/i686-redhat-linux/4.4.5/crtbegin.o -L/usr/lib/gcc/i686-redhat-linux/4.4.5 -L/usr/lib/gcc/i686-redhat-linux/4.4.5 -L/usr/lib/gcc/i686-redhat-linux/4.4.5/../../.. /tmp/ccwKgwC9.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/i686-redhat-linux/4.4.5/crtend.o /usr/lib/gcc/i686-redhat-linux/4.4.5/../../../crtn.o cis-lclient19:~/2012/sys2>./a.out Hello world cis-lclient19:~/2012/sys2> ================================================================================== 2. Simplified version of gcc script ================================================================================== cis-lclient19:~/2012/sys2>more hello.c #include main () { printf("Hello world\n"); } cis-lclient19:~/2012/sys2>more script3 #!/bin/sh /usr/libexec/gcc/i686-redhat-linux/4.4.5/cc1 -quiet hello.c -o hello3.s as hello3.s -o hello3.o /usr/libexec/gcc/i686-redhat-linux/4.4.5/collect2 \ -dynamic-linker /lib/ld-linux.so.2 \ /usr/lib/crt1.o /usr/lib/crti.o /usr/lib/gcc/i686-redhat-linux/4.4.5/crtbegin.o \ -L/usr/lib/gcc/i686-redhat-linux/4.4.5 -L/usr/lib/gcc/i686-redhat-linux/4.4.5 \ hello3.o -o hello3 \ -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed \ /usr/lib/gcc/i686-redhat-linux/4.4.5/crtend.o /usr/lib/crtn.o cis-lclient19:~/2012/sys2>script3 cis-lclient19:~/2012/sys2>more hello3.s .file "hello.c" .section .rodata .LC0: .string "Hello world" .text .globl main .type main, @function main: pushl %ebp movl %esp, %ebp andl $-16, %esp subl $16, %esp movl $.LC0, (%esp) call puts leave ret .size main, .-main .ident "GCC: (GNU) 4.4.5 20101112 (Red Hat 4.4.5-2)" .section .note.GNU-stack,"",@progbits cis-lclient19:~/2012/sys2>hello3 Hello world cis-lclient19:~/2012/sys2> ================================================================================== 3. Lets provide our own _start routine ================================================================================== cis-lclient19:~/2012/sys2>more start.s .globl _start .type _start, @function _start: call main # normal exit returns zero in %ebx movl $0, %ebx # For sys_exit system call set %eax to 1 movl $1, %eax # Call the OS with an "int" instruction int $0x80 cis-lclient19:~/2012/sys2>more script4 #!/bin/sh /usr/libexec/gcc/i686-redhat-linux/4.4.5/cc1 -quiet hello.c -o hello4.s as start.s -o start.o as hello4.s -o hello4.o ld --dynamic-linker /lib/ld-linux.so.2 -lc start.o hello4.o -o hello4 cis-lclient19:~/2012/sys2>/usr/libexec/gcc/i686-redhat-linux/4.4.5/cc1 -quiet hello.c -o hello4.s cis-lclient19:~/2012/sys2>as start.s hello4.s -o hello4.o cis-lclient19:~/2012/sys2>ld --dynamic-linker /lib/ld-linux.so.2 -lc hello4.o -o hello4 cis-lclient19:~/2012/sys2>hello4 Hello world cis-lclient19:~/2012/sys2> ================================================================================== 3. Now lets provide our own puts routine ================================================================================== cis-lclient19:~/2012/sys2>more hello5.c int printf(const char *format, ...); main () { printf("Hello world\n"); } cis-lclient19:~/2012/sys2>gcc -S -O1 hello5.c cis-lclient19:~/2012/sys2>more hello5.s .file "hello5.c" .section .rodata.str1.1,"aMS",@progbits,1 .LC0: .string "Hello world" .text .globl main .type main, @function main: pushl %ebp movl %esp, %ebp andl $-16, %esp subl $16, %esp movl $.LC0, (%esp) call puts leave ret .size main, .-main .ident "GCC: (GNU) 4.4.5 20101112 (Red Hat 4.4.5-2)" .section .note.GNU-stack,"",@progbits cis-lclient19:~/2012/sys2>more start.s .globl _start _start: call main movl $0, %ebx # normal exit returns zero in %ebx movl $1, %eax # For sys_exit system call set %eax to 1 int $0x80 # Call the OS with an "int" instruction cis-lclient19:~/2012/sys2>more puts.s .global puts puts: movl 4(%esp), %eax #address of message to write pushl %eax #to the stack call strlen #length in %eax add $4,%esp #undo push movl 4(%esp), %ecx #message to write movl %eax, %edx #message length movl $1, %ebx #file descriptor (stdout) movl $4, %eax #system call number (sys_write) int $0x80 #call kernel ret cis-lclient19:~/2012/sys2>more strlen.s .global strlen strlen: xorl %eax, %eax movl 4(%esp), %edx cmpb $0, (%edx) je .L3 .L6: addl $1, %eax cmpb $0, (%edx,%eax) jne .L6 .L3: ret cis-lclient19:~/2012/sys2>more script5 #!/bin/sh #/usr/libexec/gcc/i686-redhat-linux/4.4.5/cc1 -quiet hello5.c -o hello5.s as start.s -o start.o as puts.s -o puts.o as hello5.s -o hello5.o as strlen.s -o strlen.o ld strlen.o puts.o start.o hello5.o -o hello5 cis-lclient19:~/2012/sys2>script5 cis-lclient19:~/2012/sys2>hello5 Hello worldcis-lclient19:~/2012/sys2> cis-lclient19:~/2012/sys2>cp hello5alt.s hello5.s cis-lclient19:~/2012/sys2>more hello5.s .section .rodata .LC0: .string "Hello world" .text .globl main main: pushl $.LC0 call puts add $4, %esp ret cis-lclient19:~/2012/sys2>script5 cis-lclient19:~/2012/sys2>hello5 Hello worldcis-lclient19:~/2012/sys2>