Thread: Seg fault with inline ASM

  1. #1
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681

    Seg fault with inline ASM

    Orginally the function was in it's own ASM file and was linking it in. But to make it a little easier to trouble shoot here I did it inline. The problem is that I get a seg fault on the exit of the program. I checked the frame pointer and stack pointer before and after the function and they are identical so my function isn't screwing that up.

    Anyone have any ideas?

    Code:
    #include <stdio.h>
    
    int func (int, int);
    
    int main(void)
    {
      int x=5, y=10;
      int z = func(x,y);
      printf("%d\n", z);
      return 0;
    }
    
    int func (int x, int y)
    {
      int ret;
      asm("
          pnum1 = 8
          pnum2 = 12
          lret  = -4
          movl pnum1(%ebp), %eax
          movl pnum2(%ebp), %ebx
          addl %ebx, %eax
          movl %eax, lret(%ebp)
          ");
      return ret;
    }
    Compiler: GCC
    OS: Debian
    Warnings: None

  2. #2
    Redundantly Redundant RoD's Avatar
    Join Date
    Sep 2002
    Location
    Missouri
    Posts
    6,331
    i cant see anything wrong mike.

  3. #3
    Registered User axon's Avatar
    Join Date
    Feb 2003
    Posts
    2,572
    >>i cant see anything wrong mike.

    have you even looked? LOL

    only thing that I see is that asm should be __asm

    some entropy with that sink? entropysink.com

    there are two cardinal sins from which all others spring: Impatience and Laziness. - franz kafka

  4. #4
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    every inline assembler is different

    the syntax is correct for GCC

  5. #5
    The Artful Lurker Deckard's Avatar
    Join Date
    Jan 2002
    Posts
    633
    The EBP register needs to be restored to its original value before you return from the function. My AT&T syntax is a little rusty, so you have my apologies if EBP is not changed in your code.

    GCC stores the original value of ESP into EBP during the procedure prolog. If EBP is changed, the stack pointer will be wrong when it attempts to return, indirectly causing the instruction pointer to reference something it shouldn't.
    Jason Deckard

  6. #6
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    EBP was restored properly after the end of the function. I looked at the GCC asm output and everything look correct there also.

  7. #7
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Mmm, works OK when compiled using gcc within cygwin

    However, you really need to get rid of that explicit stack layout in your code. Quite a few compiler options could invalidate that.

    Readme
    By using the "input field" and "output field" specifications, you can refer directly to x,y,ret and it will automatically figure out where they are in memory for whatever compiler options you have.

    This isn't the best GCC ASM tutorial out there, but its the one I remember how to find
    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.

  8. #8
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    Only reason I did that part was to keep the structure "mostly" similar to the real asm file. Thanks for the tutorial. I'll have to go talk to the professor about this one.

  9. #9
    /*enjoy*/
    Join Date
    Apr 2004
    Posts
    159
    what's this ?
    Code:
    asm ("
    you can explain ?? /* this question is to any one in the forum */
    because i don't no what's --asm--

  10. #10
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    means you are about to do some inline assembly

  11. #11
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    WOOHOO!

    I figured it out. For some reason it didn't like me changing the value of ebx without changing it back. I put a push %ebx before my code and a pop %ebx at the end and it fixed it.

    Hmm of course that kinda goes against what we've been going over as far as, anything you don't want changed during a function call you protect before calling the function.

  12. #12
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    If you are going to mess with the stack in any function and combine it with any C compiler you should do the following.

    ;save ebp before we mess it up
    push ebp
    ;save current stack pointer as the base pointer
    mov ebp,esp
    ...
    ...
    ...
    ;restore ebp as if we never touched it
    ;C will happily get along with our function now
    pop ebp
    ;lets get out of here
    ret

    If you don't the stack frame will be screwed up when you get back to C. This follows your rule. See you are altering ebp inside of your function so you save it first, move the current stack pointer to the base pointer...and then do your code as offsets from ebp which is really offsets from esp or the current stack pointer. Then at the end of your code you simply restore ebp to what it was before you started screwing around with it. So ebp is exactly as it was on entry to the function. C uses ebp when you return from any function for internal purposes and you should always use this form if you are doing any stack operations within your function or if you are passing parameters via the stack.

    Also I'm not familiar with your use of temporary local variables. I normally subtract from esp to allocate space for local variables and then add it back when I clean up.

    And man do I hate AT&T syntax. Ughhh!!

  13. #13
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    Well I have done enough looking at GCC compiled code in assembly that I was fimilar with what it was doing. So ebp had already been pushed, esp moved into ebp and then esp modified to make room for the local variables, all before my own inline code started. I also knew that after words it would restore it.

    Now in my actual external function I did it all myself.

    I looked at the intel syntax this morning and personally I like AT&T better.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Code review
    By Elysia in forum C++ Programming
    Replies: 71
    Last Post: 05-13-2008, 09:42 PM
  2. weird seg fault
    By Vermelho in forum C Programming
    Replies: 3
    Last Post: 05-10-2008, 08:27 PM
  3. Certain functions
    By Lurker in forum C++ Programming
    Replies: 3
    Last Post: 12-26-2003, 01:26 AM
  4. Inline asm
    By wavering in forum C Programming
    Replies: 2
    Last Post: 01-29-2002, 02:42 AM
  5. My graphics library
    By stupid_mutt in forum C Programming
    Replies: 3
    Last Post: 11-26-2001, 06:05 PM