Search code examples
cassemblypowerpc

Assembly of Powerpc encountered Program received signal SIGSEGV Segmentation fault


When I try to store something from register to memory, I received Segmentation fault error. As I used gdb to debug line by line, it shows up Program received signal SIGSEGV when comes to the line of stb.

What I tried to do is to implement the standard C strcat function in PowerPC Assembly.

Here's the main C program, pretty simple.

#include<stdio.h>
extern char *mystrcat(char *first, char *second);
int main(){
  char *first, *second, *third;
  first = "ab";
  second = "cd";
  third = mystrcat(first, second);
  printf("%s\n", third);
  return 0;
}

And this is my mystrcat.s powerpc assembly file.

.text
    .align 2
    .globl mystrcat
mystrcat:
    mr %r5, %r3
.L1:
    lbz %r6, 0(%r5)
    cmpdi %r6, 0
    beq .L2
    addi %r5, %r5, 1
    b .L1
.L2:
    lbz %r6, 0(%r4)
    stb %r6, 0(%r5)
    addi %r4, %r4, 1
    addi %r5, %r5, 1
    cmpdi %r6, 0
    beq .L3
    b .L2
.L3:
    blr

Before the L2 label is the process finding the end of the first string. Gdb showed up "Program received signal SIGSEGV" at the second line after L2 label. The stb %r6, 0(%r5) command seems raised the error. But I just don't get it why it cannot figure out address by 0(%r5). I've tried other command seems like stbx or stbu but no one works.

Thank you for everyone can give me even just little piece of advice.

Update: I realized this has something to do with memory. Since the memory for string is readonly, is there a way that I can allocate new memory inside assembly code? I tried "bl malloc" and "nop" and the behavior beyonds my understanding.


Solution

  • In your main function, you try to concatenate 2 strings with the destination one having no room enough to copy the source one at the end.

    Trying to add a (kind of implicit) memory allocation in your function mystrcat will introduce confusion.

    Note that the segmentation fault also appears using the standard strcat that you want to mimic.

    You should fix you main function, writing something like that:

    #include <stdio.h>
    
    extern char *mystrcat(char *first, char *second);
    
    int main(){
      char first[8] = "ab";
      char *second, *third;
    
      second = "cd";
      third = mystrcat(first, second);
      printf("%s\n", third);
    
      return 0;
    }