0

Essentially, I am trying to store a char (1 byte) into memory using sb.

I am writing MIPS assembly to reproduce the functionality of some C code. I put the function str_make_lower in a separate file and compiled the C code with it.

#include <stdio.h>
/* uses tolower() to convert upper case to lower case*/
void str_make_lower(char *s);
//  while(*s != '\0'){
//      *s = tolower(*s);
//      s++;
//  }
// }


int main(int argc, char const *argv[])
{
    char *s = "AB\000";
    str_make_lower(s);
    printf("%s\n", s);
    return 0;
}

My assembly is as follows, which should mimic the C code that is commented out:

.text
.global str_make_lower
str_make_lower:
    # arg passed in:
    # a0: char *s
    addi    $sp, $sp, -40
    sw      $ra, 32($sp)
    sw      $s0, 36($sp)

    # save char *s 
    move    $s0, $a0

while_str_make_lower:
    # initialize registers
    add     $t0, $zero, $zero
    add     $a0, $zero, $zero

    lb      $t0, 0($s0)     # get a char from pointer
    beq     $t0, $zero, str_make_lower_return
    nop

    move    $a0, $t0        # load arg for tolower

    jal     tolower         # yeah
    nop

    add     $t0, $zero, $zero
    move    $t0, $v0        # collect lower letter
    sb      $t0, 0($s0)     # store it back

    addiu   $s0, $s0, 1     # increment pointer
    j       while_str_make_lower
    nop

str_make_lower_return:
    # restore and return
    lw      $s0, 36($sp)
    lw      $ra, 32($sp)
    addi    $sp, $sp, 40
    jr      $ra
    nop

Ultimately, by using gdb, I found that it was the store byte (sb) that was giving seg fault. I inspected the content of $t0 and $s0 but the values of the two seem to be what they should be. I wonder whether it is me using the sb wrong, or something else.

(gdb) p $t0
$5 = 97
Program received signal SIGSEGV, Segmentation fault.
while_str_make_lower () at tl.s:35
35      sb      $t0, 0($s0)     # store it back
(gdb) bt
#0  while_str_make_lower () at tl.s:35
#1  0x00400700 in while_str_make_lower () at tl.s:30
Backtrace stopped: previous frame identical to this frame (corrupt stack?)

(gdb) p (char*)$s0
$9 = 0x4008c0 "AB"

Thanks!

Jester
  • 54,538
  • 4
  • 72
  • 115
ngc
  • 153
  • 1
  • 1
  • 7
  • String literals may be placed in read-only memory. This is not related to your assembly code. Use `char s[] = "AB\000";` instead. – Jester Apr 02 '15 at 00:18
  • Thanks! I did not realize that, but now it's working! – ngc Apr 02 '15 at 00:31

0 Answers0