Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Segmentation fault when moving data to register

I’m trying to write a function that adds two numbers in assembly, and calling it through C. I am getting a segmentation fault when i mov eax, [ebp+8]. I know this because GDB says:

Program received signal SIGSEGV, Segmentation fault.
add () at add_two_numbers.s:12
12          mov eax, [ebp+8]

Here is my Assembly code:

    .code32
    .intel_syntax noprefix
    .global add

    .section .text
add:
    push ebp
    mov ebp, esp

    sub esp, 4

    mov eax, [ebp+8]
    add eax, [ebp+12]

    mov esp, ebp
    pop ebp
    ret

and my C Driver code:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

#include <stdio.h>

int add(int, int);

int main(void)
{
    int x = 4, y = 10;
    int z = add(x, y);
    printf("%d", z);

    return 0;
}

I Compile my code using gcc -Wall -o main driver.c add_two_numbers.s

>Solution :

After reading the manual I am now really certain of my answer.

The problem is on a modern Linux, the default output of gcc is a 64 bit binary. While .code32 tells the assembler to create 32 bit code, it doesn’t change the output file format to mark it as a 32 bit .o finally so you don’t actually get the link error you would want.

32 and 64 bit code are close enough that particular code decoded correctly; but it can’t possibly work. The problem is rsp is much higher than the 4GB barrier so mov ebp, esp didn’t put the top of the stack into it, but a sheared-off pointer that points into nilspace.

The straightforward fix is to just go ahead and write 64 bit assembly.

    .code
    .intel_syntax noprefix
    .global add

    .section .text
add:
    push rbp
    mov rbp, rsp

    sub rsp, 16  # the stack frames are 16 byte aligned so if you're going to reserve stack space, do it right!

    # Arguments are in registers rdi, rsi, rdx, rcx, r8, r9
    mov eax, edi
    add eax, esi

    mov rsp, rbp
    pop rbp
    ret
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading