Mail Archives: djgpp/1997/02/10/01:24:06
Dim Zegebart writes:
>I have in C code some structure
>typedef struct
>{ int event;
> int param1;
> int param2;
>} Events;
>[snip]
>Events EventsQueue[1000];
>
>Also I have a function
>void PostEvent(int Event,int Param1,int Param2)
>{
> [snip]
>}
>
>
>And also I have in .s file interupt handler function for com port.
>So, my questions:
>1. How can I call PostEvent with parameters from asm code?
With any question of this sort, the answer is to look at the code output
by gcc and copy it. Write a little C prog:
void PostEvent(int Event,int Param1,int Param2);
void myfunc()
{
PostEvent(1, 2, 3);
}
Compile it with 'gcc test.c -S', and you get:
_myfunc:
pushl %ebp
movl %esp,%ebp
pushl $3
pushl $2
pushl $1
call _PostEvent
addl $12,%esp
L1:
leave
ret
So, you push the parameters onto the stack in right-to-left order, call
the function (prefixing the C name with an underscore), and then pop the
parameters off the stack (three 32 bit integers takes 12 bytes, so you
add 12 to esp). In this case you don't actually need to bother repairing
esp, because the 'leave' instruction will do that anyway: if you compile
the C prog with '-O' you'll find that gcc leaves out the add.
A bit more investigation will reveal that return values are passed in
eax, and that after you call a C function the contents of eax, ecx, and
edx are likely to have changed, but ebx, esi, and edi will be preserved.
>2. How can I read and write to EventsQueue fields in asm code?
Again, look at what gcc does! Write a C prog:
typedef struct
{
int event;
int param1;
int param2;
} Events;
Events EventsQueue[1000];
int EventCounter;
void PostEvent(int Event, int Param1, int Param2)
{
EventsQueue[EventCounter].event = Event;
EventsQueue[EventCounter].param1 = Param1;
EventsQueue[EventCounter].param2 = Param2;
}
When you compile this (I used -O, because gcc produced really messy code
without it), you'll get a nice little example of exactly what you need
to do. The comments are my own additions: gcc isn't quite smart enough
to annotate the output yet :-)
_PostEvent:
pushl %ebp
movl %esp,%ebp
pushl %esi
pushl %ebx
movl 8(%ebp),%ecx // load event into ecx
movl 12(%ebp),%ebx // load param1 into ebx
movl 16(%ebp),%esi // load param2 into esi
movl _EventCounter,%eax // load array index into eax
leal (%eax,%eax,2),%eax // mul by 3 (3 ints in struct)
sall $2,%eax // mul by 4 (4 bytes in an int)
movl $_EventsQueue,%edx // load array address into edx
movl %ecx,_EventsQueue(%eax) // write event value
movl %ebx,4(%edx,%eax) // write param1 4 bytes later
movl %esi,8(%edx,%eax) // write param2 8 bytes later
leal -8(%ebp),%esp
popl %ebx
popl %esi
leave
ret
/*
* Shawn Hargreaves - shawn AT talula DOT demon DOT co DOT uk - http://www.talula.demon.co.uk/
* Ghoti: 'gh' as in 'enough', 'o' as in 'women', and 'ti' as in 'nation'.
*/
- Raw text -