`

assembly - 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 $?

------


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics