Go Down

Topic: Why runtime function address is off by 1 w.r.t. elf disassembly? (Read 440 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
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy