Escolar Documentos
Profissional Documentos
Cultura Documentos
March 5, 2007
Recursion
unsigned long factorial (unsigned long i) .globl factorial
{ .type factorial, @function
factorial:
unsigned long f=1; pushl %ebp
if (i != 0) movl %esp, %ebp
subl $4, %esp
f=i * factorial(i-1);
movl $1, -4(%ebp)
return f; cmpl $0, 8(%ebp)
} je done
movl 8(%ebp), %eax
decl %eax
pushl %eax
call factorial
addl $4, %esp
factorial (3) = 3 * factorial(2)
imull 8(%ebp), %eax
= 3 * (2 * factorial(1)) movl %eax, -4(%ebp)
= 3 * (2 * (1 * factorial(0))) done:
movl -4(%ebp), %eax
= 3 * (2 * (1 * 1)))
leave
=6 ret
EAX saves returned value
.size factorial, .-factorial
.section .rodata
main(){ .LC0:
.string "%u\n"
unsigned long i=0; .text
.globl main
i=factorial(5); main:
.type main, @function
pushl %ebp
printf("%u\n", i); movl %esp, %ebp
subl $4, %esp
} movl $0, -4(%ebp)
pushl $5
call factorial
addl $4, %esp
movl %eax, -4(%ebp)
pushl -4(%ebp)
pushl $.LC0
call printf
addl $8, %esp
leave
ret
.size main, .-main
Printf
int printf( const char *format [, argument]... );
Output:
Characters: a A
Decimals: 1977 650000
Preceding with blanks: 1977
Preceding with zeros: 0000001977
Some different radixes: 100 64 144 0x64 0144
floats: 3.14 +3e+000 3.141600E+000
Width trick: 10
A string
Using Printf in Assembly
.LC0:
.string "eax: 0x%.8X\tebx: 0x%.8X\tecx: 0x%.8X\tedx: 0x%.8X\n"
.LC1:
.string “total is %d\n“
total:
.long 333
pushl %edx
pushl %ecx
pushl %ebx
pushl %eax
pushl $.LC0
call printf
addl $20, %esp
pushl total
pushl $.LC1
call printf
addl $8, %esp
Variable argument functions
• Printf can take variable arguments.
• How does it do?
– char * format determines number and type of
variables
• How to do it in your own function?
– Must have first argument fixed
– First argument provides information about all
other arguments
Variable Parameters in C
#include <stdio.h>
#include <stdarg.h> #include <stdarg.h>
int sum( int num, ... ) { type va_arg( va_list argptr, type );
int answer = 0; void va_end( va_list argptr );
va_list argptr;
va_start( argptr, num ); void va_start( va_list argptr, last_parm );
for( ; num > 0; num-- ) {
answer += va_arg( argptr, int );
} typedef char* va_list;
va_end( argptr );
return answer; #define va_start(list) list = (char*)&va_alist
}
#define va_end(list)