Fork me on GitHub

Example for the Sept. 4th Class

by David Pcolar

01 Sep 2013

To add to the discussion for Wednesday's class, I wrote a few example lines of C and dumped the assembler code. It is interesting to see where the compiler generated the same machine code for different instructions.

C code

#include <stdio.h>
main () {
    int number; /* Declare an integer variable */
    number = 0;
    int one;
    one = 1;
    char c_one[2] = "01";
    char single[1] = "1";

    while (number < 10) {
        printf("%d \n", number);

        number++;
        number += 1;
        number = number + 1;
        number = number + one;
        number = atoi(c_one);
    }
}

Assember output via:
gcc -S -o example.s example.c
as -aljnd example.s > example.txt

    .file   "example.c"
    .section    .rodata
.LC0:
    .string "%d \n"
    .text
    .globl  main
    .type   main, @function
main:
.LFB0:
    .cfi_startproc
    pushl   %ebp                The initial value for %ebp is usually 0. 
                              This is so debuggers know when to end following the link chain in a backtrace.
                              Think of %ebp as a reference point. 
                              For convenience, it is placed between the function arguments and local variables. 
                              That way, you access arguments with a positive offset, and variables with a negative offset.


    .cfi_def_cfa_offset 8
    .cfi_offset 5, -8
    movl    %esp, %ebp              %esp - Stack Pointer
                             This register is implicitly manipulated by several CPU instructions 
                             (PUSH, POP, CALL, and RET among others), it always points to the last element 
                             used on the stack.

    .cfi_def_cfa_register 5
    andl    $-16, %esp
    subl    $32, %esp
    movl    $0, 24(%esp)            number = 0;
    movl    $1, 28(%esp)            one = 1;
    movw    $12592, 22(%esp)        move one word (2 bytes) containing the characters "01"
                            "0" is 00110000 00000000 = 12288 (dec)
                            "1" is 00000001 00110000 = 304 (dec)
    movb    $49, 21(%esp)           move one byte containing ASCII 49
    jmp .L2             Jump the the marker .L2
.L3:
    movl    24(%esp), %eax          set up the parameters for printf 
    movl    %eax, 4(%esp)
    movl    $.LC0, (%esp)
    call    printf

                        Note: compiler generates the same machine instructions
    addl    $1, 24(%esp)            number++;
    addl    $1, 24(%esp)            number += 1;
    addl    $1, 24(%esp)            number = number + 1;


    movl    28(%esp), %eax          move 'one'
    addl    %eax, 24(%esp)          add it to 'number'

    leal    22(%esp), %eax          Load effective address of 'c_one'
    movl    %eax, (%esp)              change the stack pointer the the address of 'c_one'
    call    atoi                  convert a string to integer
                            iterate through the characters of the string from left to right, 
                            updating an accumulator with the growing integer value. Initially, the accumulator is set to 0. 
                            At each character c, you multiply the accumulator by 10, and then add to it the value of the digit c
    movl    %eax, 24(%esp)          move the result back to 'number'
.L2:
                        "while (number < 10) {"
        cmpl    $9, 24(%esp)        Compares two integers. It does this by subtracting the first operand from the second
        jle .L3         jump to .L3 if number < or = 9
        leave               The compiler uses this instruction to free the used space by the function in the stack.
    .cfi_restore 5
    .cfi_def_cfa 4, 4
    ret
    .cfi_endproc
.LFE0:
    .size   main, .-main
    .ident  "GCC: (Ubuntu/Linaro 4.7.3-1ubuntu1) 4.7.3"
    .section    .note.GNU-stack,"",@progbits

References:
http://stackoverflow.com/questions/8361942/assembly-registers-esp-and-ebp http://download.intel.com/products/processor/manual/325462.pdf http://www.intel.com/content/www/us/en/processors/architectures-software-developer-manuals.html

Dave is an IT professional with the University Library. My focus is infrastructure related project management and research on scalable storage environments. Find David Pcolar on Twitter, Github, and on the web.
comments powered by Disqus