Compiled C Lab

Of all the languages I have learned thus far, one that I haven’t looked at in too much detail was the scary looking Assembly language which is architecture-specific machine language. We will be examining how this language interacts and stores information in the CPUs registers and uses the instructions accordingly.

For the purposes of this lab I have made a simple “Hello Wold” program in C that we will be breaking down using the objdump command. This will allow us to convert the machine code to an assembly language representations (it functions as a disassembler).

this carries a file size of 65 bytes and once we compile using:

gcc -g -o0 -fno-builtin hello.c

it grows into an executable of 72kb.

-g (enables debugging information) -o0 (do not optimize) -fno-builtin (don’t use builtin function optimizations).

We will now use objdump to take a look at this program under the hood…

In particular we are seeking what section contains the Hello source code and which section contains the string to be printed…

we can display header information for the entire file using objdump -f hello

Screen Shot 2017-09-23 at 11.37.13 PM

now lets try it with another argument (-s for displaying per section summary information) objdump -s hello

this quickly became a convoluted mess of numbers and odd-spaced letters all down my screen! Lets try tracking down our code…

Screen Shot 2017-09-23 at 11.36.05 PM

Ah, there it is! It seems to be in a section called .rodata, which a quick Google search informs me is a read-only data segment.

now lets use the -d argument which will disassemble sections containing code objdump -d hello

Screen Shot 2017-09-23 at 11.38.48 PM

Here we can notice there is a section titled <main> that contains a line with the instruction <printf@plt> and a memory address to the left…

The “plt” beside the printf function is the procedure linkage table, which is a structure that makes dynamic loading and linking easier to use.

Now lets see what happens when we use the –source argument (shows the source code, along with disassembly) objdump -d –source hello

Screen Shot 2017-09-23 at 11.39.59 PM

this time we can see the lines of our source code along with the assembly instructions (although it may not look pretty!), yet it seems nice to be able to know what memory addresses are being used prior and after each line of code written…

Now we will be re compiling the code with a few alternate variants to gain a better understanding of what the compiled code is doing.

Adding the compiler option -static, gcc -g -o0 -fno-builtin -static hello.c

The size of the executable with this compile grows from the original 72kb to 815kb.

Screen Shot 2017-09-23 at 1.49.36 AM

Examining the assembly code for this compile is rather taxing as there are many thousands of lines of code. After a bit of searching I found the <main> section…

Screen Shot 2017-09-23 at 1.56.05 AM

We can notice that there is a call to <_IO_printf> which is different from the previous compile. I assume the length of the file is due to the <stdio.h> library being statically linked.

Now lets see what happens when we remove the compiler option -fno-builtin..

<gcc -g -o0 hello.c>

looking at the <main> section we can see the use of <puts@plt> which is different than past compiles.

Screen Shot 2017-09-23 at 2.20.32 AM

The compiler used the call to puts() instead of printf() as it was intelligent enough to know we didn’t use any format string parameters, so it replaced the calls, as the function puts() is a bit faster.

Now we will look at what happens when we remove the -g compiler option…

<gcc -o0 hello.c>

Compared to the previous build that included the -g option the file has shrunk from 72kb to 70kb. A quick look at GCC’s debugging options list informs me that -g will produce debugging information in the operating systems native format. This leads me to believe the loss of the 2kb is due to losing the debugging information.

Looking at the <main> section it can be noticed that without the -g option there is only assembly output while when included it will display the source code of our file.

Now we will be adding additional arguments to the printf() function. I will just be using sequential integers up to the value of 10…

Screen Shot 2017-09-24 at 12.20.29 AM

When we objdump and look at the assembly code we can clearly see the 10 new arguments and their respective registers they are being inputed to, w0-w7 in this case. Registers w0 through w30 are for 32-bit-wide access. One thing that confuses me and will need to do some further research to better understand what is happening, is that after argument 7, arguments 8-10 are all placed in w0 along with the initial 0 argument. Hmmmm!….

Screen Shot 2017-09-24 at 12.45.26 AM

Now I have created a function called output() that I will place the “Hello World!” string in …

Screen Shot 2017-09-24 at 12.55.46 AM

lets see if there are any changes in the object code after moving the string to a function and calling it from main()

Well the <main> section seems to be quite a bit larger than previously without the function call. We can see the many steps the function call must take while interacting with the registers…

Screen Shot 2017-09-24 at 1.01.20 AM

now instead of using the -o0 option we will be replacing it with the –o3 option to see if we can discover any differences in the compiled code…

The objdump of both options seems to generate the same results. I will have to look into this matter further, as reading the GCC documentation it informs me that -o3 will optimize even more, opposed to -o0 (reduces compilation time and makes debugging produce the expected results).

Well that was quite interesting!! I love mysteries and it seems the world of assembly code may be the perfect one to dive further into!


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s