User:Kim Bruning/Compiler metaprogramming example
From Wikipedia, the free encyclopedia
Here is an example of how one can use a compiler to generate large amounts of assembly code. It has been linked from metaprogramming because of the length of the example.
The following programme to count from 1 to 1000 is written in C++ :
/* hello.cpp */
#include <iostream>
using std::cout;
using std::endl;
main() {
for(int i=1 ; i <= 1000 ; i++) {
std::cout << i << std::endl;
}
}
Using the GNU GCC C++ compiler g++ to generate intel x86 assembler as follows:
g++ hello.cpp -S
creates a new 221 line file hello.s as a result. The contents of this file is:
.file "hello.cpp"
.local _ZSt8__ioinit
.comm _ZSt8__ioinit,1,1
.text
.align 2
.globl main
.type main,@function
main:
.LFB1448:
pushl %ebp
.LCFI0:
movl %esp, %ebp
.LCFI1:
subl $24, %esp
.LCFI2:
andl $-16, %esp
movl $0, %eax
subl %eax, %esp
movl $1, -4(%ebp)
.L2:
cmpl $1000, -4(%ebp)
jle .L5
jmp .L3
.L5:
movl -4(%ebp), %eax
movl %eax, 4(%esp)
movl $_ZSt4cout, (%esp)
call _ZNSolsEi
movl $_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_, 4(%esp)
movl %eax, (%esp)
call _ZNSolsEPFRSoS_E
leal -4(%ebp), %eax
incl (%eax)
jmp .L2
.L3:
movl $0, %eax
leave
ret
.LFE1448:
.Lfe1:
.size main,.Lfe1-main
.align 2
.type _Z41__static_initialization_and_destruction_0ii,@function
_Z41__static_initialization_and_destruction_0ii:
.LFB1460:
pushl %ebp
.LCFI3:
movl %esp, %ebp
.LCFI4:
subl $24, %esp
.LCFI5:
cmpl $65535, 12(%ebp)
jne .L6
cmpl $1, 8(%ebp)
jne .L6
movl $_ZSt8__ioinit, (%esp)
call _ZNSt8ios_base4InitC1Ev
movl $__dso_handle, 8(%esp)
movl $0, 4(%esp)
movl $__tcf_0, (%esp)
call __cxa_atexit
.L6:
leave
ret
.LFE1460:
.Lfe2:
.size _Z41__static_initialization_and_destruction_0ii,.Lfe2-_Z41__static_initialization_and_destruction_0ii
.align 2
.type __tcf_0,@function
__tcf_0:
.LFB1461:
pushl %ebp
.LCFI6:
movl %esp, %ebp
.LCFI7:
subl $8, %esp
.LCFI8:
movl $_ZSt8__ioinit, (%esp)
call _ZNSt8ios_base4InitD1Ev
leave
ret
.LFE1461:
.Lfe3:
.size __tcf_0,.Lfe3-__tcf_0
.align 2
.type _GLOBAL__I_main,@function
_GLOBAL__I_main:
.LFB1463:
pushl %ebp
.LCFI9:
movl %esp, %ebp
.LCFI10:
subl $8, %esp
.LCFI11:
movl $65535, 4(%esp)
movl $1, (%esp)
call _Z41__static_initialization_and_destruction_0ii
leave
ret
.LFE1463:
.Lfe4:
.size _GLOBAL__I_main,.Lfe4-_GLOBAL__I_main
.section .ctors,"aw",@progbits
.align 4
.long _GLOBAL__I_main
.weak pthread_mutex_unlock
.weak pthread_mutex_trylock
.weak pthread_mutex_lock
.weak pthread_create
.weak pthread_setspecific
.weak pthread_getspecific
.weak pthread_key_delete
.weak pthread_key_create
.weak pthread_once
.section .eh_frame,"a",@progbits
.Lframe1:
.long .LECIE1-.LSCIE1
.LSCIE1:
.long 0x0
.byte 0x1
.string "zP"
.uleb128 0x1
.sleb128 -4
.byte 0x8
.uleb128 0x5
.byte 0x0
.long __gxx_personality_v0
.byte 0xc
.uleb128 0x4
.uleb128 0x4
.byte 0x88
.uleb128 0x1
.align 4
.LECIE1:
.LSFDE1:
.long .LEFDE1-.LASFDE1
.LASFDE1:
.long .LASFDE1-.Lframe1
.long .LFB1448
.long .LFE1448-.LFB1448
.uleb128 0x0
.byte 0x4
.long .LCFI0-.LFB1448
.byte 0xe
.uleb128 0x8
.byte 0x85
.uleb128 0x2
.byte 0x4
.long .LCFI1-.LCFI0
.byte 0xd
.uleb128 0x5
.align 4
.LEFDE1:
.LSFDE3:
.long .LEFDE3-.LASFDE3
.LASFDE3:
.long .LASFDE3-.Lframe1
.long .LFB1460
.long .LFE1460-.LFB1460
.uleb128 0x0
.byte 0x4
.long .LCFI3-.LFB1460
.byte 0xe
.uleb128 0x8
.byte 0x85
.uleb128 0x2
.byte 0x4
.long .LCFI4-.LCFI3
.byte 0xd
.uleb128 0x5
.align 4
.LEFDE3:
.LSFDE5:
.long .LEFDE5-.LASFDE5
.LASFDE5:
.long .LASFDE5-.Lframe1
.long .LFB1461
.long .LFE1461-.LFB1461
.uleb128 0x0
.byte 0x4
.long .LCFI6-.LFB1461
.byte 0xe
.uleb128 0x8
.byte 0x85
.uleb128 0x2
.byte 0x4
.long .LCFI7-.LCFI6
.byte 0xd
.uleb128 0x5
.align 4
.LEFDE5:
.LSFDE7:
.long .LEFDE7-.LASFDE7
.LASFDE7:
.long .LASFDE7-.Lframe1
.long .LFB1463
.long .LFE1463-.LFB1463
.uleb128 0x0
.byte 0x4
.long .LCFI9-.LFB1463
.byte 0xe
.uleb128 0x8
.byte 0x85
.uleb128 0x2
.byte 0x4
.long .LCFI10-.LCFI9
.byte 0xd
.uleb128 0x5
.align 4
.LEFDE7:
.ident "GCC: (GNU) 3.2.3 20030422 (Gentoo Linux 1.4 3.2.3-r2, propolice)"

