User:Kim Bruning/Compiler metaprogramming example

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 */
 * 1) include

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)"