1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Macros v/s Functions

Discussion in 'C' started by lionaneesh, Jun 5, 2012.

  1. In this article we'll be learning how we can improve our C code by using Macros instead of functions. How simple functions can be converted into macros to save on some CPU instructions. Some basic knowledge of C and a little bit Assembly is considered as pre-requisites.

    The Code



    We'll be testing a basic C code, that Squares a number '10' and displays it on the screen.

    Using Functions

    Function.c
    Code:
    #include<stdio.h>
    
    int SQUARE(int x)
    {
    	return (x)*(x);
    }
    int main()
    {
    	printf("%d\n", SQUARE(10));
    }
    
    Disassembly :-

    Code:
    Dump of assembler code for function main:
       0x080483d0 <+0>:	push   ebp
       0x080483d1 <+1>:	mov    ebp,esp
       0x080483d3 <+3>:	and    esp,0xfffffff0
       0x080483d6 <+6>:	sub    esp,0x10
       0x080483d9 <+9>:	mov    DWORD PTR [esp],0xa
       0x080483e0 <+16>:	call   0x80483c4 <SQUARE>
       0x080483e5 <+21>:	mov    edx,0x80484c0
       0x080483ea <+26>:	mov    DWORD PTR [esp+0x4],eax
       0x080483ee <+30>:	mov    DWORD PTR [esp],edx
       0x080483f1 <+33>:	call   0x80482f4 <printf@plt>
       0x080483f6 <+38>:	leave  
       0x080483f7 <+39>:	ret    
    End of assembler dump.
    
    Using Macros

    Macros.c
    Code:
    #include<stdio.h>
    
    #define SQUARE(x) (x)*(x)
    
    int main()
    {
    	printf("%d\n", SQUARE(10));
    } 
    
    Disassembly:-

    Code:
    Dump of assembler code for function main:
       0x080483c4 <+0>:	push   ebp
       0x080483c5 <+1>:	mov    ebp,esp
       0x080483c7 <+3>:	and    esp,0xfffffff0
       0x080483ca <+6>:	sub    esp,0x10
       0x080483cd <+9>:	mov    eax,0x80484b0
       0x080483d2 <+14>:	mov    DWORD PTR [esp+0x4],0x64
       0x080483da <+22>:	mov    DWORD PTR [esp],eax
       0x080483dd <+25>:	call   0x80482f4 <printf@plt>
       0x080483e2 <+30>:	leave  
       0x080483e3 <+31>:	ret    
    End of assembler dump.
    

    Differences



    From the Comparison above its quite trivial to note the differences :-

    1. Size

    The size of the “Function.c” bytecode is 9 bytes more than that of “Macros.c” bytecode.
    2. Instructions

    We are 12 instructions in Function.c:main, while we are using 10 instructions in Macros.c:main.

    The differences is mainly because we are actually wasting 2 instructions, 1st to load the 'esp' with the input and 2nd to Call the function. Why? Because in Macros.c, the Preprocessor actually hardcodes "10*10", instead of calling a function.

    That's all for this article stay tuned for more.
     

Share This Page