Go Down

Topic: Why runtime function address is off by 1 w.r.t. elf disassembly? (Read 421 times) previous topic - next topic

haturi

Hi all.
The runtime address of a sketch function shows up as 00080181 hex while the disassembled adr is 00080180.

1.  I would expect the elf file disassembly to show the exact placement of code in the memory.  Please correct me if I am wrong.
2. Why the cpu prefers dealing with odd addresses for code?  What am I missing here?

Here is the sketch, parts of disassembled code and the program output:-

Code: [Select]

==============================
The sketch_oct05b_funcAdrVerif
==============================

volatile uint32_t   janCount=0;
void janFunc( void)
{
    if( janCount > 20)
        janCount = 0;
}

void (*pFunc)( void) = NULL;

void myTest( void)
{
    printf( " Address of janFunc(): %08X\n", &janFunc);
    pFunc = &janFunc;

    printf( " Calling *pFunc at %08X\n", pFunc);
    delay( 200);    //  Allow printfs to complete on serial.
    (*pFunc)();
    printf( " Returned from *pFunc\n");
}

void setup() {
  // put your setup code here, to run once:
    cpu_irq_enable();
    // Open serial communications and wait for port to open:
    Serial.begin(9600);
    delay(200);
    Serial.println( "Starting Func Adr Verification.\n");
    myTest();
}

void loop() {
  // put your main code here, to run repeatedly:
 
}


=============================================================================
Relevant parts of disassembly of sketch_oct05b_funcAdrVerif.cpp.elf using the command line below:-
  arm-none-eabi-objdump -t -x -d sketch_oct05b_funcAdrVerif.cpp.elf
=============================================================================


00080180 <_Z7janFuncv>:
   80180: 4b03      ldr r3, [pc, #12] ; (80190 <_Z7janFuncv+0x10>)
   80182: 681a      ldr r2, [r3, #0]
   80184: 2a14      cmp r2, #20
   80186: d901      bls.n 8018c <_Z7janFuncv+0xc>
   80188: 2200      movs r2, #0
   8018a: 601a      str r2, [r3, #0]
   8018c: 4770      bx lr
   8018e: bf00      nop
   80190: 20070558 .word 0x20070558

00080194 <loop>:
   80194: 4770      bx lr
...

00080198 <_Z6myTestv>:
   80198: b510      push {r4, lr}
   8019a: 490a      ldr r1, [pc, #40] ; (801c4 <_Z6myTestv+0x2c>)
   8019c: 480a      ldr r0, [pc, #40] ; (801c8 <_Z6myTestv+0x30>)
...
...

=============
Runtime Output:
=============

Starting Func Adr Verification.

Address of janFunc(): 00080181
Calling *pFunc at 00080181
Returned from *pFunc




Thanks.

haturi

I may have found my answer... need to thoroughly read the Chapter-7 of SAM3X/A Datasheet but not having enough time.

I suspect the code addresses are always divisible by 2 and that leaves the bit-0 of the instruction pointer (a code address pointer in general) a tacitly assumed 0 by the cpu.  So, the bit-0 is used for carrying some other info (may be user/supervisor mode).

This answers both my questions... unless someone corrects me. :~

stimmer

On ARM the last bit in the address on a jump tells the processor whether the instructions are in ARM (32-bit) or Thumb (16-bit) format. The SAM3X only supports Thumb so the last bit in a jump address should always be 1.
Due VGA library - http://arduino.cc/forum/index.php/topic,150517.0.html

haturi

Thanks to stimmer for the full explanation! :) 

By the way, I wrote something junk about the instruction pointer.  It has little to do in this context -- the decoder was in the back of my mind when I typed out the post in a hurry.

Go Up