欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

assembly - function

程序员文章站 2022-06-05 18:36:30
...

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

------