Inline assembly

This is a discussion on Inline assembly within the C Programming forums, part of the General Programming Boards category; The code below works, but I get a "warning: control reaches end of non-void function" warning from GCC. How can ...

  1. #1
    FOX
    Join Date
    May 2005
    Posts
    188

    Inline assembly

    The code below works, but I get a "warning: control reaches end of non-void function" warning from GCC. How can I return whatever is in EAX without using an extra variable in the function?

    Code:
    unsigned long get_sp(void)
    {
            __asm__ __volatile__("movl %esp, %eax\n\t");
    }
    
    ...
    
    unsigned long sp = get_sp();

  2. #2
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,494
    Code:
    #include <stdio.h>
    
    unsigned long get_sp(void)
    {
      unsigned long result;
      __asm__ __volatile__("movl %%esp,%0":"=r"(result));
      return result;
    }
    
    int main(void)
    {
      printf( "%lx\n", get_sp() );
      return 0;
    }
    You really need to go read some tutorials on the GNU assembler syntax.
    That "=r"(result) is just the tip of the iceberg when it comes to controlling the assembler from within C programs.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

  3. #3
    FOX
    Join Date
    May 2005
    Posts
    188
    Alright thanks, but adding the result variable will increase ESP, so I'll have to accomodate it in my program. I'll go with your solution anyway though.

    I did read some GCC inline assembly HOWTO, but I just couldn't figure out how to apply it in this situation.

    > You really need to go read some tutorials on the GNU assembler syntax.
    I already know AT&T syntax.

  4. #4
    #include<xErath.h> xErath's Avatar
    Join Date
    Jun 2004
    Posts
    722
    this is what you need
    http://www.freertos.org/implementation/a00013.html

    Code:
    unsigned long get_sp(void) __attribute__ ( ( signal, naked ) )
    {
            __asm__ __volatile__("movl %esp, %eax");
            __asm__ __volatile__("ret");
    }
    naked functions have several limitations
    here's a description
    http://msdn.microsoft.com/library/de..._attribute.asp

    although it's MS, not gcc, much of that article still applies

  5. #5
    FOX
    Join Date
    May 2005
    Posts
    188
    Do I need to enable some compiler switches? This simple test program does not work, and gives me some warning messages.
    Code:
    get_sp.c:3: warning: `signal' attribute directive ignored
    get_sp.c:3: warning: `naked' attribute directive ignored
    get_sp.c: In function `get_sp':
    get_sp.c:16: warning: control reaches end of non-void function
    Code:
    #include <stdio.h>
    
    unsigned long get_sp(void) __attribute__((signal, naked));
    
    int main(void)
    {
            printf("ESP = 0x%lx\n", get_sp());
    
            return 0;
    }
    
    unsigned long get_sp(void)
    {
            __asm__ __volatile__("movl %esp, %eax");
            __asm__ __volatile__("ret");
    }

  6. #6
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,494
    > unsigned long get_sp(void) __attribute__((signal, naked));
    I have no idea what you're trying to do here.

    > I already know AT&T syntax.
    Yeah, but you've failed to get the point.
    > __asm__ __volatile__("movl %esp, %eax");
    Look again at the extended syntax I used which gets around the problem of ASSUMING that eax is the register used for the return result.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

  7. #7
    FOX
    Join Date
    May 2005
    Posts
    188
    > I have no idea what you're trying to do here.
    That was xErath's suggestion.

    > Yeah, but you've failed to get the point.
    Then explain what it was?

    > Look again at the extended syntax I used which gets around the problem of ASSUMING that eax is the register used for the return result.
    Your solution increases the stack pointer which forces me to keep track of how much the stack changes just because of that. I'd rather find a solution without additional local variables that changes the stack.

  8. #8
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,494
    > Your solution increases the stack pointer
    And your's increases it because of a function call
    In for a penny, in for a pound - it's just a different fudge to get around it.

    Perhaps you need to get the current value in ebp and not esp if you want where the stack pointer is before the call.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

  9. #9
    #include<xErath.h> xErath's Avatar
    Join Date
    Jun 2004
    Posts
    722
    Quote Originally Posted by Salem
    Look again at the extended syntax I used which gets around the problem of ASSUMING that eax is the register used for the return result.
    placing the retun value in eax is the default behaviour, like convetion calls (stdcall, fastcall, cdecl, thiscall) or or float manipulation by the co-processor. If it's not, it's almost standard (not C-standard)

  10. #10
    FOX
    Join Date
    May 2005
    Posts
    188
    Hey xErath, do you know why the code I posted doesn't even compile (in my last post with code in it)?

  11. #11
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,494
    > placing the retun value in eax is the default behaviour
    Code:
    double foo ( void ) {
      return 123.456;
    }
    
            pushl   %ebp
            movl    %esp, %ebp
            fldl    LC0
            popl    %ebp
            ret
    I see no eax

    But I recall the original question was about getting past the "function returns no value" warning from the compiler.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

  12. #12
    #include<xErath.h> xErath's Avatar
    Join Date
    Jun 2004
    Posts
    722
    Quote Originally Posted by Salem
    But I recall the original question was about getting past the "function returns no value" warning from the compiler.
    naked attribute should remove that warning.

    And, about the eax. Sorry I wasn't very explicit. eax and edx are used to return non-floating point primitive types, as big as 64bits or lower. Bigger return values need some temporary storage, and (again) floating point is handled by the co-processor. more info here (google )

    http://www.angelcode.com/dev/callcon...onv.html#cdecl
    Last edited by xErath; 07-05-2005 at 02:07 AM.

  13. #13
    FOX
    Join Date
    May 2005
    Posts
    188
    That's good to know, but I still can't manage to compile the piece of code in your first post.

  14. #14
    #include<xErath.h> xErath's Avatar
    Join Date
    Jun 2004
    Posts
    722
    how nice
    http://www.ohse.de/uwe/articles/gcc-...-searchres-2-1
    "Use this attribute on the ARM, AVR, C4x and IP2K ports" ... use what ??

    It seems attribute naked is out ot the question. And I think there's no other way to strip the prologue and epilogue code for the function. So load esp into some var, and do a regular return var;

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Help using inline assembly for keyboard input
    By sleventeen in forum C Programming
    Replies: 7
    Last Post: 05-10-2009, 01:31 AM
  2. Code review
    By Elysia in forum C++ Programming
    Replies: 71
    Last Post: 05-13-2008, 09:42 PM
  3. Arrays In Inline x86 Assembly
    By saxman in forum C Programming
    Replies: 17
    Last Post: 07-07-2004, 02:38 PM
  4. Certain functions
    By Lurker in forum C++ Programming
    Replies: 3
    Last Post: 12-26-2003, 12:26 AM
  5. inline assembly question
    By DavidP in forum C++ Programming
    Replies: 3
    Last Post: 02-10-2002, 05:14 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21