assembly - function

6004 단어 function
function, enable program broken into pieces, so that for reuse & easy to maintain,
 
------
define function
 
function is the same as normal assembly instructions,
it has a label, and use ".type label_name, @function"to tell that this is a function,
 
.type label_name, @function
      label_name is a label,
      this line says that label_name is the start of a function,
      and the function will be called via this label,
 
ret
      this line is end of function,
 
------
step to use function
 
steps:
* before call:
      * push params of function into stack in reverse order
      * call function
            call do 2 things:
            * push %eip into top of stack, this will be the return address,
            * set %eip to start address of called function, so that program will jump to function,
* inside function:
      * save %ebp to stack
      * move %esp to %ebp, so that easy to read param & make use of stack as storage,
      * read params from stack,
            the first param is at "8(%ebp)"now, because we push %ebp which take 4byte, and "call"push %eip which take 4byte,
      * 
      * do logics
      * 
      * put return value into %eax
      * restore %esp from %ebp
      * restore %ebp from stack
      * ret
            ret instruction return control to where it's called from, by pop top of stack to %eip,
            remember that before call, the return address is at the top of stack, so before ret, should restore stack to before call, this is done by restore %esp,
* after return:
      * adjust %esp to the position before push params of function,
      * get return value from %eax,

 
------
recursive function
 
each function call has it's own stack,
first push stack for all recursive function call, then release all function call & stack & do calculation,
use pushed %ebp to keep track of %esp of previous call,
 
------
calling convention
 
means the basic rule to:
* pass param
* make use of registers
 
usually:
      use stack to pass params, push in reverse order,
      use %ebp to keep track of current %esp,
      use pushed %ebp to keep track of previous %esp,
 
------
code
 
fun_sumofsquare.s
# function - sum of square

.section .data
nums:
	.long 1,2,3,4,-5
num_count:
	.long 5
.section .text
.globl _start

_start:
pushl num_count	# second param, number count
pushl $nums	# first param, start address of numbers
call square_sum # call function
addl $8, %esp	# restore stack to status before push params of function
movl %eax, %ebx	# status value for exit
jmp exit	# exit

exit:
movl $1, %eax
int $0x80

# a function to caculate sum of square
# param:
#	first param:
#		start address of numbers
#	second param:
#		count of numbers
# storage:
#	%edi:
#		count of number remain
#	%ecx:
#		address of current number
#	%ebx:
#		value & square of current number
#	%eax:
#		sum of squares
.type square_sum, @function	# function start
square_sum:
pushl %ebp	# save %ebp to stack
movl %esp, %ebp	# save %esp to %ebp, also use %esp as base address to get value from stack
movl 8(%ebp), %ecx	# read first param, start address of numbers
movl 12(%ebp), %edi	# read second param, count of numbers
movl $0, %eax

square:	# one square
cmpl $0, %edi
jle square_sum_end
movl (%ecx), %ebx
imull %ebx, %ebx
addl %ebx, %eax
decl %edi
addl $4, %ecx
jmp square

square_sum_end:	# end square function
movl %ebp, %esp		# restore %esp, for ret
popl %ebp		# restore %ebp
ret	# function end
 
fun_factorial.s
# function - factorial
.section .data
num:
	.long 5
.section .text
.globl _start

_start:
pushl num
call factorial
addl $4, %esp
movl %eax, %ebx
jmp exit

exit:
movl $1, %eax
int $0x80

.type factorial, @function
factorial:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %edi	# read num
movl $1, %eax
jmp factorial_one

factorial_one:
cmpl $1, %edi
jle factorial_end
imull %edi, %eax
decl %edi
jmp factorial_one

factorial_end:
movl %ebp, %esp
popl %ebp
ret
 
fun_factorial_recusive.s
# function - factorial recursive
.section .data
num:
	.long 5
.section .text
.globl _start

_start:
pushl num
call factorial
addl $4, %esp
movl %eax, %ebx
jmp exit

exit:
movl $1, %eax
int $0x80

# function for factorial - recursive, numbers are all pushed to stack, then do multiplication
# param:
#	first param: number
# storage:
# 	when push stack:
#		%eax -> number
#	when pop stack:
#		%ebx -> number
#		%eax -> tmp result
#	%ebx:
#		current %esp
#	pushed %ebx:
#		store last %esp
.type factorial, @function
factorial:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %eax
cmpl $1, %eax
jle factorial_end
decl %eax
pushl %eax
call factorial
movl 8(%ebp), %ebx
imull %ebx, %eax
jmp factorial_end

factorial_end:
movl %ebp, %esp
popl %ebp
ret

 
how to execute:
    as xxx.s -o a.o; ld a.o -o a.out;./a.out;echo $?
------

좋은 웹페이지 즐겨찾기