Seg Fault in ARM Assembly

1

So, I am trying to learn ARM assembly and basically what I want to do is turn on the LEDs of my BeagleBone Black using pure assembly. I know how to program in C very well, but I am new to ARM assembly if that makes any difference.

Basically I am just trying to modify a character in a string, but it doesn't seem to be working. Maybe it is because I do not fully understand the memory management instructions.

When I run the code it gives me a segmentation fault.

Here is my code:

    .syntax unified

    .global main

main:
    push    {ip, lr}

    mov     r0, beagle_bone_0
    mov     r1, #0x65
    strb    r1, [r0]
    ldr     r0, =beagle_bone_0

    bl      printf

    pop     {ip, pc}

beagle_bone_0:
    .asciz  "/sys/class/leds/beaglebone:green:usr0/brightness"

objdump -x output:

helloworld:     file format elf32-littlearm
helloworld
architecture: arm, flags 0x00000112:
EXEC_P, HAS_SYMS, D_PAGED
start address 0x00008325

Program Header:
0x70000001 off    0x00000444 vaddr 0x00008444 paddr 0x00008444 align 2**2
         filesz 0x00000008 memsz 0x00000008 flags r--
    PHDR off    0x00000034 vaddr 0x00008034 paddr 0x00008034 align 2**2
         filesz 0x00000100 memsz 0x00000100 flags r-x
  INTERP off    0x00000134 vaddr 0x00008134 paddr 0x00008134 align 2**0
         filesz 0x00000019 memsz 0x00000019 flags r--
    LOAD off    0x00000000 vaddr 0x00008000 paddr 0x00008000 align 2**15
         filesz 0x00000450 memsz 0x00000450 flags r-x
    LOAD off    0x00000450 vaddr 0x00010450 paddr 0x00010450 align 2**15
         filesz 0x00000124 memsz 0x00000128 flags rw-
 DYNAMIC off    0x0000045c vaddr 0x0001045c paddr 0x0001045c align 2**2
         filesz 0x000000f0 memsz 0x000000f0 flags rw-
    NOTE off    0x00000150 vaddr 0x00008150 paddr 0x00008150 align 2**2
         filesz 0x00000044 memsz 0x00000044 flags r--
   STACK off    0x00000000 vaddr 0x00000000 paddr 0x00000000 align 2**2
         filesz 0x00000000 memsz 0x00000000 flags rwx

Dynamic Section:
  NEEDED               libc.so.6
  INIT                 0x000082d1
  FINI                 0x00008439
  INIT_ARRAY           0x00010450
  INIT_ARRAYSZ         0x00000004
  FINI_ARRAY           0x00010454
  FINI_ARRAYSZ         0x00000004
  HASH                 0x00008194
  GNU_HASH             0x000081bc
  STRTAB               0x00008238
  SYMTAB               0x000081e8
  STRSZ                0x00000043
  SYMENT               0x00000010
  DEBUG                0x00000000
  PLTGOT               0x0001054c
  PLTRELSZ             0x00000020
  PLTREL               0x00000011
  JMPREL               0x000082b0
  REL                  0x000082a8
  RELSZ                0x00000008
  RELENT               0x00000008
  VERNEED              0x00008288
  VERNEEDNUM           0x00000001
  VERSYM               0x0000827c

Version References:
  required from libc.so.6:
    0x0d696914 0x00 02 GLIBC_2.4
private flags = 5000002: [Version5 EABI] [has entry point]

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .interp       00000019  00008134  00008134  00000134  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  1 .note.ABI-tag 00000020  00008150  00008150  00000150  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  2 .note.gnu.build-id 00000024  00008170  00008170  00000170  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  3 .hash         00000028  00008194  00008194  00000194  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  4 .gnu.hash     0000002c  000081bc  000081bc  000001bc  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  5 .dynsym       00000050  000081e8  000081e8  000001e8  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  6 .dynstr       00000043  00008238  00008238  00000238  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  7 .gnu.version  0000000a  0000827c  0000827c  0000027c  2**1
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  8 .gnu.version_r 00000020  00008288  00008288  00000288  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  9 .rel.dyn      00000008  000082a8  000082a8  000002a8  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 10 .rel.plt      00000020  000082b0  000082b0  000002b0  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 11 .init         0000000a  000082d0  000082d0  000002d0  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 12 .plt          00000048  000082dc  000082dc  000002dc  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 13 .text         00000114  00008324  00008324  00000324  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 14 .fini         00000006  00008438  00008438  00000438  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 15 .rodata       00000004  00008440  00008440  00000440  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 16 .ARM.exidx    00000008  00008444  00008444  00000444  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 17 .eh_frame     00000004  0000844c  0000844c  0000044c  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 18 .init_array   00000004  00010450  00010450  00000450  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 19 .fini_array   00000004  00010454  00010454  00000454  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 20 .jcr          00000004  00010458  00010458  00000458  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 21 .dynamic      000000f0  0001045c  0001045c  0000045c  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 22 .got          00000020  0001054c  0001054c  0000054c  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 23 .data         00000008  0001056c  0001056c  0000056c  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 24 .bss          00000004  00010574  00010574  00000574  2**0
                  ALLOC
 25 .comment      0000001d  00000000  00000000  00000574  2**0
                  CONTENTS, READONLY
 26 .ARM.attributes 00000031  00000000  00000000  00000591  2**0
                  CONTENTS, READONLY
SYMBOL TABLE:
00008134 l    d  .interp    00000000              .interp
00008150 l    d  .note.ABI-tag  00000000              .note.ABI-tag
00008170 l    d  .note.gnu.build-id 00000000              .note.gnu.build-id
00008194 l    d  .hash  00000000              .hash
000081bc l    d  .gnu.hash  00000000              .gnu.hash
000081e8 l    d  .dynsym    00000000              .dynsym
00008238 l    d  .dynstr    00000000              .dynstr
0000827c l    d  .gnu.version   00000000              .gnu.version
00008288 l    d  .gnu.version_r 00000000              .gnu.version_r
000082a8 l    d  .rel.dyn   00000000              .rel.dyn
000082b0 l    d  .rel.plt   00000000              .rel.plt
000082d0 l    d  .init  00000000              .init
000082dc l    d  .plt   00000000              .plt
00008324 l    d  .text  00000000              .text
00008438 l    d  .fini  00000000              .fini
00008440 l    d  .rodata    00000000              .rodata
00008444 l    d  .ARM.exidx 00000000              .ARM.exidx
0000844c l    d  .eh_frame  00000000              .eh_frame
00010450 l    d  .init_array    00000000              .init_array
00010454 l    d  .fini_array    00000000              .fini_array
00010458 l    d  .jcr   00000000              .jcr
0001045c l    d  .dynamic   00000000              .dynamic
0001054c l    d  .got   00000000              .got
0001056c l    d  .data  00000000              .data
00010574 l    d  .bss   00000000              .bss
00000000 l    d  .comment   00000000              .comment
00000000 l    d  .ARM.attributes    00000000              .ARM.attributes
0000835c l     F .text  00000000              call_gmon_start
00000000 l    df *ABS*  00000000              crtstuff.c
00010458 l     O .jcr   00000000              __JCR_LIST__
00008374 l     F .text  00000000              __do_global_dtors_aux
00010574 l     O .bss   00000001              completed.5637
00010454 l     O .fini_array    00000000              __do_global_dtors_aux_fini_array_entry
00008384 l     F .text  00000000              frame_dummy
00010450 l     O .init_array    00000000              __frame_dummy_init_array_entry
000083b8 l       .text  00000000              beagle_bone_0
00000000 l    df *ABS*  00000000              crtstuff.c
0000844c l     O .eh_frame  00000000              __FRAME_END__
00010458 l     O .jcr   00000000              __JCR_END__
00010454 l       .init_array    00000000              __init_array_end
0001045c l     O .dynamic   00000000              _DYNAMIC
00010450 l       .init_array    00000000              __init_array_start
0001054c l     O .got   00000000              _GLOBAL_OFFSET_TABLE_
00008434 g     F .text  00000002              __libc_csu_fini
0001056c  w      .data  00000000              data_start
000082f0       F *UND*  00000000              printf@@GLIBC_2.4
00010574 g       *ABS*  00000000              __bss_start__
00010578 g       *ABS*  00000000              _bss_end__
00010574 g       *ABS*  00000000              _edata
00008438 g     F .fini  00000000              _fini
00010578 g       *ABS*  00000000              __bss_end__
0001056c g       .data  00000000              __data_start
000082fc       F *UND*  00000000              __libc_start_main@@GLIBC_2.4
00000000  w      *UND*  00000000              __gmon_start__
00010570 g     O .data  00000000              .hidden __dso_handle
00008440 g     O .rodata    00000004              _IO_stdin_used
000083f0 g     F .text  00000044              __libc_csu_init
00010578 g       *ABS*  00000000              _end
00008324 g     F .text  00000000              _start
00010578 g       *ABS*  00000000              __end__
00010574 g       *ABS*  00000000              __bss_start
0000839c g       .text  00000000              main
00000000  w      *UND*  00000000              _Jv_RegisterClasses
00008318       F *UND*  00000000              abort@@GLIBC_2.4
000082d0 g     F .init  00000000              _init
c
assembly
beagleboneblack
asked on Stack Overflow Dec 7, 2014 by schmidt73 • edited Dec 7, 2014 by schmidt73

2 Answers

1

The answer to my question was actually really simple. Since ldr r0, =beagle_bone_0 loads the address of beagle_bone_0 into register 0 I can just manipulate beagle_bone_0 with that address.

Working test code:

    .syntax unified

    .data

beagle_bone_0:  .ascii  "Hello, world\n"

    .text

    .global main

main:
    push    {ip, lr}

    ldr     r0, =beagle_bone_0
    mov     r1, #0x65
    strb    r1, [r0]

    bl      printf

    pop     {ip, pc}
answered on Stack Overflow Dec 7, 2014 by schmidt73
0

I ran and debugged your code. The line mov r0, beagle_bone_0 didn't even compile (on my compiler, at least). You want to load in r0 the address of beagle_bone. For this, you should use the adr pseudo-instruction, that is translated by the compiler in a pc-relative move (something like mov r0, [pc, #8]. You cannot use it this way. Probably your compiler translated it into something different.

So, to fix it, just replace the line mov r0, beagle_bone_0 by adr r0, beagle_bone_0.

Also the string was in the .text section which we cannot edit. So, I put beagle_bone_0 in the .data section.

answered on Stack Overflow Dec 7, 2014 by Paul92 • edited Dec 7, 2014 by Ben Affleck

User contributions licensed under CC BY-SA 3.0