llvm-gcc assembler: LDR syntax

2020-02-07 06:19发布

问题:

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

回答1:

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



回答2:

There are two things you can try:

  1. Change ldr r7, =maskTable into adr r7, maskTable.
  2. 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


回答3:

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.