Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 15 Mar 1996 15:56:56 -0800
From:      John Polstra <jdp@polstra.com>
To:        nate@sneezy.sri.com
Cc:        freebsd-hackers@freebsd.org
Subject:   Re: GAS question
Message-ID:  <199603152356.PAA02917@austin.polstra.com>

next in thread | raw e-mail | index | archive | help
> Can someone explain to me the following piece of code please?  I
> can't find *any* documentation on it, and I've stared at it long
> enough but still can't answer what it does definitively.
> ...
> inline int
> apm_int(u_long *eax, u_long *ebx, u_long *ecx)
> {
>         u_long cf;
>         __asm ("pushl   %%ebp
>                 pushl   %%edx
>                 pushl   %%esi
>                 xorl    %3,%3
>                 movl    %3,%%esi
>                 lcall   _apm_addr
>                 jnc     1f
>                 incl    %3
>         1:
>                 popl    %%esi
>                 popl    %%edx
>                 popl    %%ebp"
>                 : "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=D" (cf)
>                 : "0" (*eax),  "1" (*ebx),  "2" (*ecx)
>                 );
>         apm_errno = ((*eax) >> 8) & 0xff;
>         return cf;
> }
> 
> 
> Most of this is obvious, but these two lines completely baffle me.
> 
> : "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=D" (cf)
> : "0" (*eax),  "1" (*ebx),  "2" (*ecx)

This is GCC's "extended asm" syntax.  The documentation is in the GCC
info pages.  From the top-level node, follow the menu entry "C
Extensions", then "Extended Asm".

Here's a quick answer for this specific case.  The stuff after the
first colon specifies the output operands of the assembly code.
The stuff after the second colon specifies the input operands.
The quoted strings are GCC "constraints," which say more or less
specifically where each operand will be.  In parentheses is the
corresponding C expression for each operand.

For the output operands, the constraints here refer to specific hardware
registers:

    "a" means %eax
    "b" means %ebx
    "c" means %ecx
    "D" means %edi

The "=" on each output operand is required by gcc; it says that the
operand will be modified.

For the input operands, the "0", "1", and "2" say that the three inputs
correspond in location to the first three output operands.  In other
words, these operands are read, modified, and written back to the same
place.

In the assembly code itself, "%3" refers to third operand.  For
this, the operands are numbered from 0, output operands first, then
input operands.  Here, "%3" refers to the local variable "cf",
which, according to its constraint "=D", is in the register %edi.

Someday when you're feeling masochistic, you can read all about it in
the info pages.

Let me know if this doesn't help enough.

-- John



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199603152356.PAA02917>