Search code examples
cassemblysegmentation-faultx86-64calling-convention

Segmentation fault in assembly when multiplying registers?


I was trying to convert the following C code into assembly. Here is the C code:

typedef struct {
    int x;
    int y;
} point;


int square_distance( point * p ) {
    return p->x * p->x + p->y * p->y;  
}

My assembly code is as follows:

square_distance:

.LFB23:
    .cfi_startproc
    movl    (%edi), %edx
    imull   %edx, %edx
    movl    4(%edi), %eax
    imull   %eax, %eax
    addl    %edx, %eax
    ret
    .cfi_endproc

I get a segmentation fault when I try to run this program. Could someone please explain why? Thanks! I would be grateful!


Solution

  • Your code is 32 bit code (x86) but you apply the calling convention used with 64 bit code (x64). This can obviously not work.

    The x86 calling convention is passing all parameters on the stack.

    The x64 calling convention is passing the first parameter in rdi, the second in rsi, the third in rdx, etc. (I'm not sure which registers are used if there are more than 3 parameters, this might also depend on your platform).

    Your code is presumably more or less correct for x64 code, that would be something like this:

    square_distance:
        movl    (%rdi), %edx
        imull   %edx, %edx
        movl    4(%rdi), %eax
        imull   %eax, %eax
        addl    %edx, %eax
        ret
    

    With x86 code the parameters are passed on the stack and the corresponding correct code would be something like this:

    square_distance:
        movl    4(%esp), edx
        movl    (%edx), eax
        imull   eax, eax
        movl    4(%edx), edx
        imull   edx, edx
        addl    edx, eax
        ret
    

    In general the Calling conventions subject is vast, there are other calling conventions depending on the platform and even within the same platform different calling conventions can exist in certain cases.