www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1997/02/10/01:24:06

From: Shawn Hargreaves <Shawn AT talula DOT demon DOT co DOT uk>
Newsgroups: comp.os.msdos.djgpp
Subject: Re: Some Asm and C questions.
Date: Sat, 8 Feb 1997 15:54:39 +0000
Organization: None
Distribution: world
Message-ID: <YkdF+IA$GK$yEwpa@talula.demon.co.uk>
References: <32FBBA4C DOT 5582 AT post DOT comstar DOT ru>
NNTP-Posting-Host: talula.demon.co.uk
MIME-Version: 1.0
Lines: 109
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp

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 -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019