OSDev.org

The Place to Start for Operating System Developers
It is currently Fri Nov 17, 2017 6:45 pm

All times are UTC - 6 hours




Post new topic Reply to topic  [ 5 posts ] 
Author Message
 Post subject: Assembly: Passing Values From C
PostPosted: Sat Sep 17, 2016 1:26 am 
Offline
Member
Member

Joined: Fri Aug 07, 2015 6:13 am
Posts: 869
I need some quick help.
How do I do this:
Code:
C code:
void MyFunction(void* test1, void* test2, size_t size)
{
     MyFunctionDoAssembly(test1, test2, size);
}
NASM Code:
MyFunctionDoAssembly:
    mov test1, esi
    mov test2, edi
    mov size, ebx

_________________
OS: Basic OS, Monolithic Kernel, Written in C++
Current Task: Learning NASM!
Forever monolithic! Don't let the micro people reassure you.


Top
 Profile  
 
 Post subject: Re: Assembly: Passing Values From C
PostPosted: Sat Sep 17, 2016 2:10 am 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 1174
Somewhere in your C code you'll need a function declaration. (Usually, this will go in one of your .h files.)
Code:
void MyFunction(void* test1, void* test2, size_t size);


In your assembly code, you'll need to appropriately declare the function.
Code:
global MyFunction

section .text
MyFunction:
    ;your code here


The name you need to use in your assembly code depends on your ABI, but the most common ABIs use the same name in both assembly and C. GCC has some helpful function attributes that you can use to change the ABI, in case the defaults are inconvenient.


Top
 Profile  
 
 Post subject: Re: Assembly: Passing Values From C
PostPosted: Sat Sep 17, 2016 2:50 am 
Offline
Member
Member
User avatar

Joined: Thu Mar 10, 2016 7:35 am
Posts: 130
Location: Lancaster, England, Disunited Kingdom
octacone wrote:
I need some quick help.
How do I do this:
Code:
C code:
void MyFunction(void* test1, void* test2, size_t size)
{
     MyFunctionDoAssembly(test1, test2, size);
}
NASM Code:
MyFunctionDoAssembly:
    mov test1, esi
    mov test2, edi
    mov size, ebx


I am assuming you are asking about how to get at the location of the variables test1, test2 etc.
Forgive me if I seem to be teaching you to suck eggs, but if you haven't worked at assembly level before you may not know some of this.

Firstly, you must know how yor C code will carry out the calling of "MyFunctionDoAssembly", called the 'calling convention'

Traditional C put size, test2, and test1 onto the stack and then did a call instruction. This is called the C calling convention and note that the parameters go on to the stack from the end i.e. backwards. There are good reasons for doing this, principally to allow C to implement functions with varying numbers of parameters, like printf, but that doesn't need to be explained in detail here. Another issue is whether the caller or the called function 'cleans up the stack' at the end of the call. An advantage of the C calling convention from your point of view is that the caller is responsible, so your assembler function doesn't have to worry about that

An alternative method is to use the Pascal or Standard calling conventions in which the parameters are put on the stack forwards, or a register calling convention where the parameters don't go on to the stack at all and are passed in registers.

To be sure what happens you should declare your functions with an explicit calling convention and I'm using the C convention as an example here: "_cdecl void MyFunctionDoAssembly

The start of your function can then be like this:

push ebp ;Save ebp so the calling routine gets it back in tact
mov ebp esp ;ebp now provides a stable pointer into the stack

The stack (working upwards from what ebp points to) now looks this this


ebp -> Currently the value of esp, but esp may alter during your routine
[ebp+4] Old value of ebp that you have just pushed
[ebp+8] Return address for getting back to the calling function
[ebp+12] *test1 [Lowest in memory, pushed on to the stack most recently]
[ebp+16] *test2
[ebp+20] size4 [Highest in memory, pushed on to the stack first by the caller]

so mov test1,esi is coded mov [ebp+12], esi

{{EDIT}}

Whoops! What a load of rubbish
[ebp+12] is of course a pointer to your real object so you will almost certainly require something like:

mov ebx [ebp+12]
mov [ebx] esi

or, if test1 is a structure:

mov [ebx+someoffset] esi

{{End edit}}

and when you've finished:

pop ebp
ret

Caveats
-----------

Don't know where you're writing your assembler function. If, for example, you are using inbuilt facilities within your compiler it may do some of this work for you and so you should not duplicate it. If your using a separate assembler, then it will also have conventions you can use to simplify all this. I've also assumed you're using a flat 32 bit model.


Top
 Profile  
 
 Post subject: Re: Assembly: Passing Values From C
PostPosted: Sat Sep 17, 2016 5:08 am 
Offline
Member
Member
User avatar

Joined: Mon Dec 28, 2015 11:11 am
Posts: 366
Location: Serbia
Exactly.

_________________
Website


Top
 Profile  
 
 Post subject: Re: Assembly: Passing Values From C
PostPosted: Sun Sep 18, 2016 7:31 am 
Offline
Member
Member

Joined: Fri Aug 07, 2015 6:13 am
Posts: 869
Octocontrabass wrote:
reply

MichaelFarthing wrote:
reply


Thank you guys. That is what I was looking for.

_________________
OS: Basic OS, Monolithic Kernel, Written in C++
Current Task: Learning NASM!
Forever monolithic! Don't let the micro people reassure you.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 5 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: Bing [Bot] and 5 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group