I'm doing a part C, part Assembly code but I'm getting a segmentation fault. And I haven't figured out why? Can anyone help?

#include <stdio.h>

#define SZ 7

int* a[SZ];
int x, y, z;

void populate() {
  x = 1;
  y = 2;
  z = 3;
  a[0] = &x;
  a[1] = &y;
  a[2] = &z;
  a[3] = a[0];
  a[4] = a[1];
  a[5] = a[2];
  a[6] = a[3];
}
void printall() 
{
  for(int i = 0; i < SZ; i++) 
  {
    printf("a[%1d]=%1d, ", i, *(a[i]));
  }
  printf("x=%1d, y=%1d, z=%1d\n", x, y, z);
}

void add1each()
{
 __asm__("\
	pushl	%ebp\n\
	movl	%esp, %ebp\n\
	subl	$23, %esp\n\
	movl	$0, -4(%ebp)\n\
	jmp	compare\n\
increment:\n\
	movl	-4(%ebp), %eax\n\
	movl	a(,%eax,4), %eax\n\
	movl	-4(%ebp), %edx\n\
	movl	a(,%edx,4), %edx\n\
	movl	(%edx), %edx\n\
	addl	$1, %edx\n\
	movl	%edx, (%eax)\n\
	addl	$1, -4(%ebp)\n\
compare:\n\
	cmpl	$6, -4(%ebp)\n\
	jle	increment\n\
	leave\n\
	ret\n\
	");
}

int main(int argc, char* argv[]) {
  populate();
  printall();
  add1each();
  printall();
  return 0;
}

Thanks in Advance

Hi,
I do not work with at&t syntax but I believe that:

movl $0, -4(%ebp)\n\ --You move zero to the first 4 bytes of local space.

jmp compare\n\
increment:\n\
movl -4(%ebp), %eax\n\ --You move to eax the value inside the first 4 bytes of local space (zero):
movl a(,%eax,4), %eax\n\ --You move to eax the content of the address pointed for eax. eax has the value zero. You are trying to read at the memory address zero (null pointer) == Memory error == Program crashes

Cheers.

Hi,
This time more seriously.
Your program is very very useful to learn many things about inline assembly. Indeed very useful. Here is the corrected version:

#include <stdio.h>

#define SZ 7



int* a[SZ];
int x, y, z;

void populate() {

  x = 1;
  y = 2;
  z = 3;
  a[0] = &x;
  a[1] = &y;
  a[2] = &z;
  a[3] = a[0];
  a[4] = a[1];
  a[5] = a[2];
  a[6] = a[3];
}
void printall() 
{
    int i;
  for( i = 0; i < SZ; i++) 
  {
    printf("a[%1d]=%1d, ", i, *(a[i]));
  }
  printf("x=%1d, y=%1d, z=%1d\n", x, y, z);
}

void add1each(int *a[SZ])
{
 __asm__("\
    movl    8(%ebp), %ecx\n\
	subl	$23, %esp\n\
	movl	$0, -4(%ebp)\n\
	jmp	compare\n\
    increment:\n\
	movl	-4(%ebp), %eax\n\
	movl	(%ecx,%eax,4), %eax\n\
	movl	-4(%ebp), %edx\n\
	movl	(%ecx,%edx,4), %edx\n\
	movl	(%edx), %edx\n\
	addl	$1, %edx\n\
	movl	%edx, (%eax)\n\
	addl	$1, -4(%ebp)\n\
    compare:\n\
	cmpl	$6, -4(%ebp)\n\
	jle	increment\n\
	addl   $23, %esp\n\
	");
}

int main(int argc, char* argv[]) {
  populate();
  printall();
  add1each(a);
  printall();
  getchar();
  return 0;
}

As you can see, in my version of the procedure, there is no the definition of an stack frame. This was your error. And I have learned the truth thanks to you.
The C compiler creates an stack frame. If you saw the assembly output, the pop with ebp and the assignation of esp to ebp happened twice. And likewise with the return code.

Do not care about my previous post. And thank you. I have learned something new thanks to you.

Cheers.

This article has been dead for over six months. Start a new discussion instead.