Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

writing functions in assembler

Tags:

assembly

nasm

I am writing code in assembler (nasm) and I want to include functions, at the moment I have

function0:

code

jmp return0

the function is called with a jump to function0 with the return linking to a label below where the function is called, however this only works if the function is called once, is there a better way to do this?

like image 893
PStag Avatar asked Mar 01 '16 23:03

PStag


People also ask

How are functions called in assembly?

A function is called with the instruction “call foo”. This instruction transfers the control of the program to foo function. The two special registers ebp (base pointer) and esp (stack pointer) handles call and return mechanisms of function calls. The values are returned to the calling program via register eax.

Does assembly language have functions?

Assembly language doesn't truly have functions, just the tools to implement that concept, e.g. jump and store a return address somewhere = call , indirect jump to a return address = ret . On x86, return addresses are pushed and popped on the stack.

How do we get into a function in assembly language?

The assembly language function begins by first pushing BP (EBP) onto the stack and moving the stack pointer into BP (EBP). This permits access to the variables pushed onto the stack by the calling function. This is done by using BP (EBP) to point to offsets within the stack.

How are function parameters passed in assembly?

To pass parameters to a subroutine, the calling program pushes them on the stack in the reverse order so that the last parameter to pass is the first one pushed, and the first parameter to pass is the last one pushed. This way the first parameter is on top of the stack and the last one is at the bottom of the stack.


2 Answers

(assuming NASM x86)

Use call in order to call the function and ret to return from the function.

What occurs when you type call is that the address of the next instruction is pushed into the stack. When ret is hit, it will pop that address off the stack and jmp to it.

func:
    xor eax, eax
    mov eax, 10
    add eax, 5
    ret ;// essentially identical to: pop [register] -> jmp [register]


_start:
    call func
    mov ebx, eax ;// Address of this instruction is pushed onto the stack
    ;// ebx is now 15

Calling convention dictates that the EAX register should contain the return value. Also note that the __cdecl calling convention takes parameters on the stack. Take a look at the examples in the afore-linked page. The NASM function will set up its stack frame and take parameters from the stack in order to use in the function. The value is stored in EAX.

like image 51
Goodies Avatar answered Sep 28 '22 19:09

Goodies


Here is a new, very easy way to write functions in assembly (with many return values):

function:
    sub esp, ( 4 * ret_count)
    pushad
    mov ebp, esp

    ;code
    ;acces first argument with ( dword[ebp + 32 + (4*ret_count) + (4*arg_num)]
    ;write first return value with ( mov dword[ebp + 36 + (4*ret_pointer)]
    popad
    add esp, ( 4 * ret_count)
    ret

After that, you can access return values like this:

call function
mov eax, dword[esp] ; 1st ret
mov ebx, dword[esp - 4] ; 2nd ret

; or you can just pop them : 
pop eax
pop ebx
like image 44
Tazerout Islam Avatar answered Sep 28 '22 21:09

Tazerout Islam