Jump to content

User:Kim Bruning/Compiler metaprogramming example

From Wikipedia, the free encyclopedia
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

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