[Top][All Lists]
[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