C may be considered a higher level assembly language as the power constructs in assembly are also available in C; concepts such as pointers, unrestricted gotos, and the like. In fact a C compiler worth its salt should be able to generate assembly output!
For the hello world example in C, we try to write in an undiciplined manner and see if we can get away it. As usual we write a function to do the actual writing of a message "hello world!" to be closer in spirit to the previous Javascript example. Save the following to a file "hello.c" without the quotes.
void showMessage(char *str) { puts(str); } main() { showMessage("Hello World"); }
Every C program has a main function. The difference between a function and procedure is that the former exlicitly returns a value while a procedure does not and should be declared of type void. Now lets try to run the hello.c code in the console: type
gcc -Wall hello.c
Notice the -Wall flag to output any warnings encountered in processing the source file.
Here is the output from my Ubuntu 10.04 terminal (console):
gcc -Wall hello.c
hello.c: In function ‘showMessage’:
hello.c:4: warning: implicit declaration of function ‘puts’
hello.c: At top level:
hello.c:8: warning: return type defaults to ‘int’
hello.c: In function ‘main’:
hello.c:10: warning: control reaches end of non-void function
toto@toto-laptop:~/Blogs/my-other-life-as-programmer/C$
In good C programs, all functions must be declared and return types should be explicit. Here the compiler complains that puts was implicitly declared and that the main function did not return any value! and yet in spite of these warnings, you will find that the gcc outputte an executible file hello. To run this ececutible, issue ./hello. The program outputs
toto@toto-laptop:~/Blogs/my-other-life-as-programmer/C$ ./a.out
Hello World
toto@toto-laptop:~/Blogs/my-other-life-as-programmer/C$
Now a good C programmer tries to remove all warnings. So lets do some modifications to be in good terms with the gcc compiler.
#includevoid showMessage(char *str) { puts(str); } int main() # explicit declaration. { showMessage("Hello World"); return 0; }
We have included the standard header "stdio.h", gcc knows where to find it (in "/usr/include") and this erases the warning on puts. We also explicitly declare the main function as type int and specifically return a zero (the usual value for successful execution.) The compilation is now successful without any complaints from the compiler.
toto@toto-laptop:~/Blogs/my-other-life-as-programmer/C$ gcc -Wall hello.c
toto@toto-laptop:~/Blogs/my-other-life-as-programmer/C$
So the minor corrections removed all warnings. Now lets do some extra activities for fun.
- Create assembler listing Type gcc -S hello.c this outputs hello.s
- Seek help in using gcc Try man gcc. You will get an eyeful to the useful flags. Better yet, try the free forums or buy a book specifically on the gcc.
.file "hello.c" .text .globl showMessage .type showMessage, @function showMessage: .LFB0: .cfi_startproc pushq %rbp .cfi_def_cfa_offset 16 movq %rsp, %rbp .cfi_offset 6, -16 .cfi_def_cfa_register 6 subq $16, %rsp movq %rdi, -8(%rbp) movq -8(%rbp), %rax movq %rax, %rdi call puts leave ret .cfi_endproc .LFE0: .size showMessage, .-showMessage .section .rodata .LC0: .string "Hello World" .text .globl main .type main, @function main: .LFB1: .cfi_startproc pushq %rbp .cfi_def_cfa_offset 16 movq %rsp, %rbp .cfi_offset 6, -16 .cfi_def_cfa_register 6 movl $.LC0, %edi call showMessage movl $0, %eax leave ret .cfi_endproc .LFE1: .size main, .-main .ident "GCC: (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5" .section .note.GNU-stack,"",@progbitsThe assembler file is one reason most programmers (run away) do not like assembly language! ha ha. Unless of course if the paying job calls for using assmbly (or assembler) langauge. ! But this feature of the gcc to ouput assembler will come in handy when we program a Forth language translator.
No comments:
Post a Comment