How C program converts into assembly?
Tags: c, cpp, computerscience, programming
Published: 2019-11-01 10:17:55

<!-- wp:paragraph -->
<p>In an earlier article, we have seen <a rel="noreferrer noopener" aria-label="C runtime: before starting main (opens in a new tab)" href="http://www.vishalchovatiya.com/before-starting-main-c-runtime/" target="_blank"><span style="color:#0d23e6" class="color">C runtime: before starting main</span></a> &amp; <a rel="noreferrer noopener" aria-label="How C program stored in RAM memory (opens in a new tab)" href="http://www.vishalchovatiya.com/how-c-program-stored-in-ram-memory/" target="_blank"><span style="color:#1039ec" class="color">How C program stored in RAM memory</span></a>. Here we will see "How C program converts into assembly?"  and different aspect of its working at the machine level.</p>
<!-- /wp:paragraph -->

> /!\\\: Originally published @ [www.vishalchovatiya.com](http://www.vishalchovatiya.com).

<!-- wp:heading -->
<h2>A bit about functions stack frames</h2>
<!-- /wp:heading -->

<!-- wp:list -->
<ul><li>During function code execution, a new stack frame is created in stack memory to allow access to function parameters and local variables. </li><li>The direction of stack frame growth totally depends on compiler ABI which is out of our scope for this article.</li><li>The complete information on stack frame size, memory allocation, returning from stack frame is decided at compile time.</li><li>Before diving into assembly code you should be aware of two things <ol><li>CPU registers of x86 machine.</li><li>x86 assembly instructions: As this is a very vast topic &amp; updating quite frequently, we will only see the instructions needed for our examples.</li></ol></li></ul>
<!-- /wp:list -->

<!-- wp:heading -->
<h2>x86 CPU Registers</h2>
<!-- /wp:heading -->

<!-- wp:heading {"level":3} -->
<h3>General Purpose Registers</h3>
<!-- /wp:heading -->

<!-- wp:table {"backgroundColor":"subtle-light-gray","className":"is-style-regular"} -->
<table class="wp-block-table has-subtle-light-gray-background-color has-background is-style-regular"><tbody><tr><td><strong>32-bit SFR</strong></td><td><strong>64-bit  SFR </strong></td><td><strong>Name</strong></td></tr><tr><td>eax</td><td> rax </td><td>Accumulator uses for arithmetic</td></tr><tr><td>ebx</td><td> rbx </td><td>Base uses for memory address calculations </td></tr><tr><td>ecx</td><td> rcx  </td><td>Counter uses to hold loop count</td></tr><tr><td>edx</td><td> rdx  </td><td> Double-word Accumulator or data register use for I/O port access </td></tr></tbody></table>
<!-- /wp:table -->

<!-- wp:heading {"level":3} -->
<h3>Pointer Register</h3>
<!-- /wp:heading -->

<!-- wp:table {"backgroundColor":"subtle-light-gray"} -->
<table class="wp-block-table has-subtle-light-gray-background-color has-background"><tbody><tr><td> <strong>32-bit SFR</strong> </td><td> <strong>64-bit SFR</strong> </td><td><strong>Name</strong> </td></tr><tr><td> esp </td><td>rsp  </td><td>Stack pointer </td></tr><tr><td> ebp </td><td>rbp  </td><td>Frame/base pointer points current stack frame</td></tr><tr><td>eip</td><td>rip</td><td>Instruction pointer points to the next instruction to execute</td></tr></tbody></table>
<!-- /wp:table -->

<!-- wp:heading {"level":3} -->
<h3>Segment Register</h3>
<!-- /wp:heading -->

<!-- wp:table {"backgroundColor":"subtle-light-gray"} -->
<table class="wp-block-table has-subtle-light-gray-background-color has-background"><tbody><tr><td><strong>SFR</strong>  </td><td><strong>Name</strong></td></tr><tr><td>cs</td><td>Code segment</td></tr><tr><td>ds</td><td>Data segment </td></tr><tr><td>ss</td><td>Stack segment </td></tr><tr><td>es</td><td>Extra segment </td></tr></tbody></table>
<!-- /wp:table -->

<!-- wp:heading {"level":3} -->
<h3>Index Registers</h3>
<!-- /wp:heading -->

<!-- wp:table {"backgroundColor":"subtle-light-gray"} -->
<table class="wp-block-table has-subtle-light-gray-background-color has-background"><tbody><tr><td><strong>32-bit SFR</strong>   </td><td><strong>64-bit SFR</strong>   </td><td><strong>Name</strong></td></tr><tr><td> esi </td><td> rsi </td><td>Source Index uses to point index in sequential memory operations</td></tr><tr><td> edi </td><td> rdi </td><td>Destination Index uses to point index in sequential memory operations </td></tr></tbody></table>
<!-- /wp:table -->

<!-- wp:paragraph -->
<p>Apart from all these, there are many other registers as well which even I don't know about. But above-mentioned registers are sufficient to understand the subsequent topics.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2>How C program converts into assembly?</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>We will consider the following example with its disassembly inlined to understand its different aspect of working at machine level :</p>
<!-- /wp:paragraph -->


![Note: Similar colour on both sides represents assembly corresponding to C expression](https://thepracticaldev.s3.amazonaws.com/i/cjzy7gtoa5omozylax0a.png)


<!-- wp:paragraph -->
<p>We will focus on a stack frame of the function <code>func()</code>. But before analysing stack frame of it, we will see how the calling of function happens:</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3>Function calling</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Function calling is done by <code>call</code> instruction(see Line 15) which is subroutine instruction equivalent to : </p>
<!-- /wp:paragraph -->

<!-- wp:enlighter/codeblock {"language":"asm","linenumbers":"false"} -->
<pre class="EnlighterJSRAW" data-enlighter-language="asm" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">push rip + 1 ; return address is address of next instructions
jmp func</pre>
<!-- /wp:enlighter/codeblock -->

<!-- wp:paragraph -->
<p>Here, <code>call</code> store the <code>rip+1</code> in the stack which is return address once call to <code>func()</code> ends. </p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3>Function stack frame</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>A function stack frame is divided into three parts</p>
<!-- /wp:paragraph -->

<!-- wp:list {"ordered":true} -->
<ol><li><a rel="noreferrer noopener" aria-label="Prologue (opens in a new tab)" href="https://en.wikipedia.org/wiki/Function_prologue" target="_blank"><span style="color:#0e0be5" class="color">Prologue</span></a>/Entry</li><li>User code</li><li><a rel="noreferrer noopener" aria-label="Epilogue (opens in a new tab)" href="https://en.wikipedia.org/wiki/Function_prologue#Epilogue" target="_blank"><span style="color:#1a16de" class="color">Epilogue</span></a>/Exit</li></ol>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p><strong>1. Prologue/Entry:</strong> As you can see instructions(line 2 to 4) generated against start bracket <code>{</code> is prologue which is setting up the stack frame for <code>func()</code>, Line 2 is pushing the previous frame pointer into the stack &amp; Line 3 is updating the current frame pointer with stack end which is going to be a new frame start.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p><code>push</code> is basically equivalent to :</p>
<!-- /wp:paragraph -->

<!-- wp:enlighter/codeblock {"language":"asm","linenumbers":"false"} -->
<pre class="EnlighterJSRAW" data-enlighter-language="asm" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">sub esp, 4   ; decrements ESP by 4 which is kind of space allocation
mov [esp], X ; put new stack item value X in</pre>
<!-- /wp:enlighter/codeblock -->

<!-- wp:heading {"level":3} -->
<h3>Parameter Passing </h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Argument of <code>func()</code> is stored in <code>edi</code> register on Line 14 before calling <code>call</code> instruction. If there is more argument then it will be stored in a subsequent register or stack &amp; address will be used. Line 4 in <code>func()</code> is reserving space by pulling frame pointer(pointed by <code>rbp</code> register) down by 4 bytes for the parameter <code>arg</code> as it is of type <code>int</code>. Then <code>mov</code> instruction will initialize it with value store in<code>edi</code>. This is how parameters are passed &amp; stored in the current stack frame.</p>
<!-- /wp:paragraph -->

<!-- wp:enlighter/codeblock {"linenumbers":"false"} -->
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">          ---|-------------------------|--- main()
             |                         |          
             |                         |          
             |                         |          
             |-------------------------|          
             |    main frame pointer   |          
rbp &amp; rsp ---|-------------------------|--- func()
in func()    |           arg           |          
             |-------------------------|          
             |            a            |          
             |-------------------------|    stack
             |            +            |      |  
             |            +            |      |  
             |            +            |      |  
          ---|-------------------------|---  \|/  
             |                         |          
             |                         |          
                                                   </pre>
<!-- /wp:enlighter/codeblock -->

<!-- wp:heading {"level":3} -->
<h3>Allocating Space for Local Variables</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p><strong>2. </strong> <strong>User</strong> <strong>code: </strong>Line 5 is reserving space for a local variable <code>a</code>, again by pulling frame pointer further down by 4 bytes. <code>mov</code> instruction will initialize that memory with a value <code>5</code>. </p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3>Accessing global &amp; local static variables</h3>
<!-- /wp:heading -->

<!-- wp:list -->
<ul><li> As you can see above, <code>g</code> is addressed directly with its absolute addressing because its address is fixed which lies in the data segment.</li><li>This is not the case all the time. Here we have compiled our code for  &nbsp;x86 mode, that's why it is accessing it with an absolute address.</li><li>In the case of x64 mode, the address is resolved using <code>rip</code> register which meant that the assembler and linker should cooperate to compute the offset of <code>g</code> from the ultimate location of the current instruction which is pointed by <code>rip</code> register.</li><li> The same statement stands true for the local static variables also. </li></ul>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p><strong>3. Epilogue/Exit:</strong> After the  user code execution, the previous frame pointer is retrieved from the stack by <code>pop</code> instruction which we have stored in Line 2. <code>pop</code> is equivalent to: </p>
<!-- /wp:paragraph -->

<!-- wp:enlighter/codeblock {"language":"asm","linenumbers":"false"} -->
<pre class="EnlighterJSRAW" data-enlighter-language="asm" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">mov X, [esp] ; put top stack item value into X
add esp, 4   ; increments ESP by 4 which is kind of deallocation</pre>
<!-- /wp:enlighter/codeblock -->

<!-- wp:heading {"level":3} -->
<h3><strong>Return</strong> from function</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p><code>ret</code> instruction jumps back to the next instruction from where <code>func()</code> called by retrieving the jump address from stack stored by <code>call</code> instruction.  <code>ret</code> is subroutine instruction which is equivalent to:</p>
<!-- /wp:paragraph -->

<!-- wp:enlighter/codeblock {"language":"asm","linenumbers":"false"} -->
<pre class="EnlighterJSRAW" data-enlighter-language="asm" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">pop rip ;
jmp rip ;</pre>
<!-- /wp:enlighter/codeblock -->

<!-- wp:paragraph -->
<p>If any return value specified then it will be stored in <code>eax</code> register which you can see in Line 16.  </p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>In case, you have not gone through my previous articles, here are simple FAQs helps you to understand better: </p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2>FAQs </h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p><strong>Q.  How do you determine the stack growth direction ?</strong></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p><strong>A. </strong>Simple...! by comparing the address of two different function's local variables.</p>
<!-- /wp:paragraph -->

<!-- wp:enlighter/codeblock {"language":"c"} -->
<pre class="EnlighterJSRAW" data-enlighter-language="c" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">int *main_ptr = NULL;
int *func_ptr = NULL;

void func() { int a; func_ptr = &a; }

int main()
{
    int a; main_ptr = &a;

    func();

    (main_ptr > func_ptr) ? printf("DOWN\n") : printf("UP\n");

    return 0;
}</pre>
<!-- /wp:enlighter/codeblock -->

<!-- wp:paragraph -->
<p><strong>Q.  How do you corrupt stack deliberately ?</strong></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p><strong>A.  </strong>Corrupt the SFR values stored in the stack frame.</p>
<!-- /wp:paragraph -->

<!-- wp:enlighter/codeblock {"language":"c"} -->
<pre class="EnlighterJSRAW" data-enlighter-language="c" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">void func()
{
    int a;
    memset(&amp;a, 0, 100); // Corrupt SFR values stored in stack frame
}

int main()
{
    func();
    return 0;
}
</pre>
<!-- /wp:enlighter/codeblock -->

<!-- wp:paragraph -->
<p><strong>Q.  How you can increase stack frame size ?</strong></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p><strong>A. </strong>  <code>alloca()</code> is the answer. Google about it or see <a rel="noreferrer noopener" aria-label="this (opens in a new tab)" href="http://man7.org/linux/man-pages/man3/alloca.3.html" target="_blank"><span style="color:#1a0fe3" class="color">this</span></a>.</p>
<!-- /wp:paragraph -->


## Other related articles

- [How floating-point no is stored in memory?](https://dev.to/visheshpatel/how-floating-point-no-is-stored-memory-47od)
- [How do malloc & free work in C?](https://dev.to/visheshpatel/how-do-malloc-free-work-in-c-3mb6)
- [How C program stored in RAM memory?](https://dev.to/visheshpatel/how-c-program-stored-in-ram-memory-3773)


[Have any suggestions, query or wants to say `Hi`? Take the Pressure Off, you are just a click away.](http://www.vishalchovatiya.com/contact-2/)🖱️