Accessing function args from the stack relative to EBP while pushing/popping other registers?

Viewed 88

I am writing an assembly program and a C program; the C program will call a function written in assembly. The environment is Ubuntu 18.04LTS x64.

It is designed for 32 bits x86 and will be compiled by NASM, but it can't pass correct parameters.

To simplify the problem, I just changed my function to get the sum of a and b.

extern int FindPattern(int a,int b);

int result;
result=FindPattern(1,1);
printf("%d\n",result);
global FindPattern
 section .text
FindPattern:
    push    ebp
    push    esi
    push    edi
    push    ebx
    push    edx
    push    ecx
    
    mov     ebp,esp
    mov     esi,[ebp+8]     ; a
    mov     edi,[ebp+12]    ; b
    mov     eax,0
    add     eax,esi
    add     eax,edi         ; return a+b
    
    pop     ecx
    pop     edx
    pop     ebx
    pop     edi               
    pop     esi
    pop     ebp
    ret          

The function just adds a and b, and returns the sum. The sum should be 2, however I got a random number like 1449041840. It seems the assembly didn't get correct parameters.

What's wrong with the code and how can I fix it?

# Makefile
cc=gcc
ASMBIN=nasm

all : asm cc link
asm:
    $(ASMBIN) -o findpattern.o -f elf32 -l findpattern.lst findpattern.asm
cc :
    $(cc) -m32 -c -g -O0 -fpack-struct graph_io.c
link :
    $(cc) -m32 -o graph_io findpattern.o graph_io.o 
clean:
    rm *.o
    rm graph_io
    rm findpattern.lst
1 Answers

Your stack frame set up is wrong. push ebp; mov ebp, esp must be issued before any other stack movement takes place.

By pushing other stuff on the stack before setting up ebp you have set up ebp to point to a different place than usual, causing all the offsets to be different. To fix this, first set up the stack frame, then push the remaining registers:

global FindPattern
 section .text
FindPattern:
    push    ebp
    mov     ebp,esp

    push    esi
    push    edi
    push    ebx
    push    edx
    push    ecx
    
    mov     esi,[ebp+8]     ; a
    mov     edi,[ebp+12]    ; b
    mov     eax,0
    add     eax,esi
    add     eax,edi         ; return a+b
    
    pop     ecx
    pop     edx
    pop     ebx
    pop     edi               
    pop     esi
    pop     ebp
    ret 
Related