0
########
# int mycompare( int size, int x[], int y[] )
#
.text
.global mycompare

mycompare:
    pushl %ebp
    movl %esp, %ebp
    subl $4 , %esp
    movl $0 , -4(%ebp)

    movl 12(%ebp), %edx # int x[]
    movl 16(%ebp), %ebx # int y[]
    mov $0, %ecx
ciclo:
    cmp 8(%ebp) , %ecx
    je fim

    mov (%edx,%ecx,4), %eax
    cmp (%ebx,%ecx,4), %eax
    jne fim_wrong
    inc %ecx
    jmp ciclo

fim_wrong:
    mov %ecx, %eax

    mov %ebp, %esp
    pop %ebp
    ret

fim:
    mov $0xFFFFFFFF, %eax

    mov %ebp, %esp
    pop %ebp
    ret

And the c Main


#include <stdio.h>
#include <stdlib.h>

#define MAX 1024
#define MAXLINE 2048

extern int mycompare( int size, int x[], int y[] );


int readOneArr(int max, int a[]) {
    char line[MAXLINE];
    if (fgets(line, MAXLINE, stdin) == NULL) exit(1);
    int i=0;
    char *curr;
    char *new=line;
    do {
        curr=new;
        a[i] = strtol(curr, &new, 10);
        i++;
    } while (i<max && curr!=new);
    return i-1;
}

int readArrs(int max, int a[], int b[]) {
    int na = readOneArr( max, a );
    int nb = readOneArr( max, b );
    if (na!=nb) return -1;
    return na;
}

int main() {
    int i, n;
    int a1[MAX], a2[MAX];

    n = readArrs(MAX, a1, a2);
    if(n == -1) {
        fprintf(stderr,"wrong input!\n");
        return 1;
    }
    i=mycompare(n, a1, a2);
    if ( i == -1 )
        printf("equal\n");
    else
        printf("different at %d\n", i);
    return 0;
}


I use the following cc settings to compile

cc -m32 -Wall -std=c11 -o main.c func.s

Its a program that compares two arrays of integers returning the first index where they differ, or -1 if the arrays are equal. The arrays have the same size and that size is also an argument for the function.

Its giving me :

Segmentation fault (core dumped)

If i try for example to input:

1 2 4 7 10 
1 2 4 7 10 
Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
  • You should try to run this through a debugging tool, e.g. `valgrind` is quite useful to investigate segmentation faults. This will help you pin point around where in your code things are going wrong. – Julien Thierry May 09 '20 at 17:32
  • 1
    On x86 with SysV calling conventions, `ebx` is supposed to be preserved by function calls. Your `mycompare` function needs to save its value and restore it when it returns (e.g. by push/pop). – Nate Eldredge May 09 '20 at 17:37
  • You only need 2 pointers and a temporary; you can implement this with only EAX, ECX, and EDX. If you want to use indexed addressing modes and a separate index you'll need a 4th register, so then yes you'd have to save/restore another one of the call-preserved regs to use as a temporary, like you're doing with EBP. – Peter Cordes May 09 '20 at 17:46
  • Just as a note, when I tried fixing this by adding `pushl %ebx / popl %ebx` just after/before the `mov %esp, %ebp`, it still didn't work, because it gets overwritten by your `movl $0 , -4(%ebp)`. But that line is pointless anyway so you might as well remove it. Then the code works. – Nate Eldredge May 09 '20 at 17:48
  • @NateEldredge when you ```push ebx``` shouldnt it be before the ```mov %esp, %ebp````and poping it later in for the "fim" – Mauricio Polvora May 09 '20 at 18:28
  • 1
    @MauricioPolvora: Well, you could, but then you'll have to adjust all the offsets from `%ebp` that you use for the parameters. It's more common to do push/pops after setting the frame pointer. – Nate Eldredge May 09 '20 at 19:47

0 Answers0