assemblyarmarm64armv8

Segmentation Fault at LDR X10, [X9, #0]


I have tried to write an ARM-LEGv8 assembler program that calculates the average of two values in an array at a certain position. It runs on a Raspberry Pi with Armbian.

The pseudo code should look like this:

int average(int v[], int i){
  int average = (v[i] + v[i-1])/2;
  return average;
}

The array is at X0 and the i on X1.

My assembly code looks like this:

.globl _start

.data
myArray: .word 0, 1, 2, 3, 35, 5

.text


average:
  LSL X9, X1, #2
  ADD X9, X9, X0
  LDR X10, [X9, #0] // guess Segmentation Fault 
  LDUR X11, [X9, #-4]
  ADD X3, X10, X11  
  LSR X3, X3, #1 
  BR X30

_start:
  LDR X0, myArray
  MOV X1, #5
  BL mittelwert


  MOV X8, #0x5d
  MOV X0, X3
  SVC 0

I used these commands to build it:

as average.s -o average.o

gcc average.o -o average -nostdlib -static

When I run my program I get a Segmentation Fault. Why?


Solution

  • (Disclaimer: the following is based on the actual ARMv8-A instruction set. I'm not sure what changes LEGv8 may have made.)

    LDR X0, myArray doesn't load X0 with the address of the label myArray. It loads a doubleword from that address (ARM calls this the "literal" form of the load instruction). So after this instruction, X0 contains 0x0000000100000000 which naturally results in an invalid pointer by the time you do LDR X10, [X9, #0].

    You may have meant LDR X0, =myArray which will place a pointer to myArray into the literal pool, then assemble a literal load of that pointer from its address in the pool. That would work, assuming your system can handle that type of relocation. However, for modern position-independent executables used by common operating systems, the preferred method is

    ADR X0, myArray
    ADD X0, X0, #:lo12:myArray
    

    The first instruction populates the high 52 bits of X0 with those bits of the address of myArray, using an offset from PC. The second adds in the low 12 bits. See also Understanding ARM relocation (example: str x0, [tmp, #:lo12:zbi_paddr])


    A couple other bugs and remarks: