This code compiles just fine on gcc, but when using llvm (llvm-gcc), it says "constant expression expected"
on the line with ldr
The problem is the syntax: How do I specify the place where my array is? I do not want to hard-code the displacement in bytes: ldr r7, [pc, #some_shift]
but to use a literal to keep the code clean and safe.
Any idea how to make it working?
.globl func_name
func_name:
push {r4, r5, r6, r7, r8, r9, sl, fp, ip, lr}
//[Some stripped code]
add r6, r6, sl, lsl #2
sub ip, ip, sl
ldr r7, =maskTable // Here it crashes
add sl, sl, #4 @ 0x4
// Some stripped code here
mov r0, #0 @ 0x0 // return 0
pop {r4, r5, r6, r7, r8, r9, sl, fp, ip, pc}
.word 0x00000000
.data
.align 5
maskTable:
.word 0x00000000, 0x00000000, 0x00000000, 0x00000000
.word 0x0000FFFF, 0x00000000, 0x00000000, 0x00000000
.word 0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000
Try changing
ldr r7, =maskTable
to
ldr r7, maskTable
and remove
.data
section. It seems to be a bug/missing capability of gcc < 4.6 to deal with .data
section
There are two things you can try:
- Change
ldr r7, =maskTable
into adr r7, maskTable
.
- Store the address of the table under a separate label and load it manually like follows:
.globl func_name
func_name:
push {r4, r5, r6, r7, r8, r9, sl, fp, ip, lr}
//[Some stripped code]
add r6, r6, sl, lsl #2
sub ip, ip, sl
ldr r7, maskTable_adr // Here it crashes
add sl, sl, #4 @ 0x4
// Some stripped code here
mov r0, #0 @ 0x0 // return 0
pop {r4, r5, r6, r7, r8, r9, sl, fp, ip, pc}
.word 0x00000000
.data
.align 5
maskTable_adr:
.word maskTable
maskTable:
.word 0x00000000, 0x00000000, 0x00000000, 0x00000000
.word 0x0000FFFF, 0x00000000, 0x00000000, 0x00000000
.word 0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000
I don't know the answer myself, but if it was me, I'd look at some compiled C code, and see how the compiler does it. Make sure that the compiler isn't in PIC mode, or something, or it'll do something more complicated and unnecessary.