Assembly trouble

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Assembly trouble

549 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by ant on Tue Apr 26 08:17:02 MST 2011
If I put the data before the code, I get an error that says

Error: invalid offset, value too big (0xFFFFFFF0)
The code that gets the error looks like this:  
ldr r1, .ttt

That number 0xFFFFFFF0 is not the number I put in, but rather is generated by the assembler, saying that the data is -16 bytes offset from the PC, which is well within range of the instruction from what I read.

This one, generated from C code, gets the same error: 
ldr    r2, .L39+36

If I put the data after the code, then the last line of the code gets highlighted as the error, and I get five lines of error saying "undefined reference to labelname"

I tried each of these as the last line, with the same result.
     bx    lr       
     b    asm_test
     pop    {r7, pc}

I'm using a LPC1113

Tony
0 Kudos
Reply
5 Replies

496 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by larryvc on Wed Apr 27 09:42:16 MST 2011
Zero, This is the one of the best posts on defining the align directive that I have found.  It has definitely cleared up my misunderstanding of how it worked.

Thank You,
Larry
0 Kudos
Reply

496 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Ex-Zero on Wed Apr 27 06:40:47 MST 2011
Align is aligning the next address with:

align x, address is aligned to 2^x  :eek:

So 'align 2' = word alignment

A simple 'align' is interpreted as 'align 2'

You can watch this effect in your disassembly or asm output.

Example:

.align 4
is aligning to next 0Xxxx0

.align 3
is aligning to next 0Xxxx0 or 0Xxxx8

.align 2
is aligning to next 0Xxxx0 or 0Xxxx4 0Xxxx8 or 0XxxxC


You can test that with a simple:
.align 4
    nop //1
.align 4
    nop //2
.align 3
    nop //3
.align 3
    nop //4
.align 3
    nop //5
.align 3
    nop //6
.align 2
    nop //7
.align 2
    nop //8
.align 2
    nop //9
.align 2
    nop    //10
Result:

Quote:

    nop //1
0x00000320 <asm_test>:    nop   ; (mov r8, r8)
0x00000322 <asm_test+2>:  nop   ; (mov r8, r8)
0x00000324 <asm_test+4>:  nop   ; (mov r8, r8)
0x00000326 <asm_test+6>:  nop   ; (mov r8, r8)
0x00000328 <asm_test+8>:  nop   ; (mov r8, r8)
0x0000032a <asm_test+10>: nop   ; (mov r8, r8)
0x0000032c <asm_test+12>: nop   ; (mov r8, r8)
0x0000032e <asm_test+14>: nop   ; (mov r8, r8)
    nop //2
0x00000330 <asm_test+16>: nop   ; (mov r8, r8)
0x00000332 <asm_test+18>: nop   ; (mov r8, r8)
0x00000334 <asm_test+20>: nop   ; (mov r8, r8)
0x00000336 <asm_test+22>: nop   ; (mov r8, r8)
    nop //3
0x00000338 <asm_test+24>: nop   ; (mov r8, r8)
0x0000033a <asm_test+26>: nop   ; (mov r8, r8)
0x0000033c <asm_test+28>: nop   ; (mov r8, r8)
0x0000033e <asm_test+30>: nop   ; (mov r8, r8)
    nop //4
0x00000340 <asm_test+32>: nop   ; (mov r8, r8)
0x00000342 <asm_test+34>: nop   ; (mov r8, r8)
0x00000344 <asm_test+36>: nop   ; (mov r8, r8)
0x00000346 <asm_test+38>: nop   ; (mov r8, r8)
    nop //5
0x00000348 <asm_test+40>: nop   ; (mov r8, r8)
0x0000034a <asm_test+42>: nop   ; (mov r8, r8)
0x0000034c <asm_test+44>: nop   ; (mov r8, r8)
0x0000034e <asm_test+46>: nop   ; (mov r8, r8)
    nop //6
0x00000350 <asm_test+48>: nop   ; (mov r8, r8)
0x00000352 <asm_test+50>: nop   ; (mov r8, r8)
    nop //7
0x00000354 <asm_test+52>: nop   ; (mov r8, r8)
0x00000356 <asm_test+54>: nop   ; (mov r8, r8)
    nop //8
0x00000358 <asm_test+56>: nop   ; (mov r8, r8)
0x0000035a <asm_test+58>: nop   ; (mov r8, r8)
    nop //9
0x0000035c <asm_test+60>: nop   ; (mov r8, r8)
0x0000035e <asm_test+62>: nop   ; (mov r8, r8)
    nop    //10
0x00000360 <asm_test+64>: nop   ; (mov r8, r8)

Note: Byte alignment is done with[INDENT] .balign x

Sample: .balign 4      //4 byte (=word) alignment

[/INDENT]
0 Kudos
Reply

496 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by ant on Tue Apr 26 23:34:25 MST 2011
Ok, that explains why putting the data before causes errors, but it doesn't explain the error on the last line. That's ok though, 'cause I got it working with your template, except for a few changes.

According to the LPC111x manual, it is cortex-m0, but you had cortex-m3. Changing it to cortex-m0 caused errors on two instructions, (mov r2, #100 and sub r4, r5). I removed the  .syntax unified and then it worked. So here's what I got, that works (or at least seems to work).

Also, I don't understand why it is ".align 2", shouldn't that be just .align or .align 4? Seems odd to me.


Quote:
    .cpu cortex-m0
    .thumb
    .align 2
    .global    asm_test
    .thumb_func
asm_test:
    ldr r6, .timer32b0base
    ldr    r5, [r6, #8] // timer value
    mov r2, #100
    ldr r1, .timer16b0base
    str r2, [r1, #0x18] // Timer16B0 Match Reg 0
    ldr    r4, [r6, #8] // timer value
    sub r4, r5
    ldr r1, .rambase
    str r4, [r1]

    bx    lr

    .align    2
.timer32b0base:    .word 0x40014000    // timer 32b0
.timer16b0base:    .word 0x4000C000    // timer 16b0
.rambase:        .word 0x10000000

.end

0 Kudos
Reply

496 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Ex-Zero on Tue Apr 26 12:42:48 MST 2011
I think he created an old fashioned negative offset instead a positive like:

    .syntax unified
     .cpu cortex-m3
     .thumb
     .align 2
     .global    asm_test

.thumb_func
asm_test:
     ldr r3, .mydata
     bx    lr
     .align    2
.mydata:
    .word 0x12345678
0 Kudos
Reply

496 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by jharwood on Tue Apr 26 12:18:10 MST 2011
According to the manual, the 16 bit Thumb LDR instruction can have a PC relative offset of 0 to 1020 and must be a multiple of 4. Do you have a '.align 2' directive before the local data?

Can you post a complete section of your code showing the problem?
0 Kudos
Reply