avr-gcc-list
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [avr-gcc-list] Function pointer problem


From: Ned Konz
Subject: Re: [avr-gcc-list] Function pointer problem
Date: Sat, 2 Oct 2004 10:42:05 -0700
User-agent: KMail/1.7

On Saturday 02 October 2004 7:09 am, Thomas Olsson wrote:
> It always produces the wrong address, I have not been able to change that
> at all.
>
> For the record, this is GCC-avr 3.4.1.

I don't see this, at least with the code I just tested. You have to remember 
that GCC can spot a lot of uses of constants, etc.

Look at this:


// avr-gcc -Os -g -mmcu=atmega16  -Wall xx3.c
// avr-objdump -S a.out > xx3.disasm

#include <inttypes.h>
#include <avr/io.h>

volatile uint8_t keep_gcc_guessing;

typedef void (*fp_t) (uint8_t);

fp_t code;

void fn1 (uint8_t arg) { }
void fn2 (uint8_t arg) { }
void fn3 (uint8_t arg) { }

fp_t functions[] = { &fn1, &fn2, &fn3 };

void code_init(uint8_t xx) { code = functions[ keep_gcc_guessing = xx ]; }

int main(void)
{
 keep_gcc_guessing = 1;
    code_init(keep_gcc_guessing + 1);
    code(1);
    return 0;
}


which produces this (abridged) assembly code:


void fn1 (uint8_t arg) { }
  8e: 08 95        ret

00000090 <fn2>:
void fn2 (uint8_t arg) { }
  90: 08 95        ret

00000092 <fn3>:
void fn3 (uint8_t arg) { }
  92: 08 95        ret

00000094 <code_init>:

fp_t functions[] = { &fn1, &fn2, &fn3 };

void code_init(uint8_t xx) { code = functions[ keep_gcc_guessing = xx ]; }
  94: 80 93 66 00  sts 0x0066, r24
  98: 80 91 66 00  lds r24, 0x0066
  9c: e8 2f        mov r30, r24
  9e: ff 27        eor r31, r31
  a0: ee 0f        add r30, r30
  a2: ff 1f        adc r31, r31
  a4: e0 5a        subi r30, 0xA0 ; 160
  a6: ff 4f        sbci r31, 0xFF ; 255
  a8: 80 81        ld r24, Z
  aa: 91 81        ldd r25, Z+1 ; 0x01
  ac: 90 93 68 00  sts 0x0068, r25
  b0: 80 93 67 00  sts 0x0067, r24
  b4: 08 95        ret

000000b6 <main>:

int main(void)
{
  b6: cf e5        ldi r28, 0x5F ; 95
  b8: d4 e0        ldi r29, 0x04 ; 4
  ba: de bf        out 0x3e, r29 ; 62
  bc: cd bf        out 0x3d, r28 ; 61
 keep_gcc_guessing = 1;
  be: 11 e0        ldi r17, 0x01 ; 1
  c0: 10 93 66 00  sts 0x0066, r17
    code_init(keep_gcc_guessing + 1);
  c4: 80 91 66 00  lds r24, 0x0066
  c8: 81 0f        add r24, r17
  ca: 0e 94 4a 00  call 0x94
    code(1);
  ce: e0 91 67 00  lds r30, 0x0067
  d2: f0 91 68 00  lds r31, 0x0068
  d6: 81 2f        mov r24, r17
  d8: 09 95        icall
    return 0;
}
  da: 80 e0        ldi r24, 0x00 ; 0
  dc: 90 e0        ldi r25, 0x00 ; 0
  de: 0c 94 71 00  jmp 0xe2

000000e2 <_exit>:
  e2: ff cf        rjmp .-2       ; 0xe2


If you look at the code from 0xCE to 0xD8 you will see the right thing being 
done (I believe) (0x67 is the address of code).

-- 
Ned Konz
http://bike-nomad.com



reply via email to

[Prev in Thread] Current Thread [Next in Thread]