I use "c:\Programme\sdcc2.5\bin\sdcc -v
SDCC : mcs51/gbz80/z80/avr/ds390/pic16/pic14/TININative/xa51/ds400/hc08 2.5.2 #1102 (Aug 26 2005) " with the option --mcs51 and want use function pointers, but they didn't work (generate wrong assembler code)
struct Status_FT_12
{
void (*action)(void); ///<function pointer calls the given function of the status machine table
unsigned char following_state; ///<status machine status
};
In the assembler code I'm missing the jump order to the function pointer.
Is this a bug, or do I something wrong?
Thanks for your help
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Anonymous
-
2006-01-09
The last ret instruction does the call. If I read the code correctly, ar2 and ar3 contain the function pointer from the table. These are pushed into the stack just before ret is executed. Ret pops the return address off the stack and jumps there, in this case it will be address given by r2 and r3.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I use "c:\Programme\sdcc2.5\bin\sdcc -v
SDCC : mcs51/gbz80/z80/avr/ds390/pic16/pic14/TININative/xa51/ds400/hc08 2.5.2 #1102 (Aug 26 2005) " with the option --mcs51 and want use function pointers, but they didn't work (generate wrong assembler code)
Example:
-------------------------------------------------
-------------------------------------------------
void TX_A1(void);
void TX_A2(void);
void TX_A3(void);
void TX_A4(void);
struct Status_FT_12
{
void (*action)(void); ///<function pointer calls the given function of the status machine table
unsigned char following_state; ///<status machine status
};
const struct Status_FT_12 TRANSMITER_TABLE[2][2]=
{
// TX_START_BYTE_1 TX_LENGTH_1
/*EV_DATA_BYTE */ {{TX_A1,0} ,{TX_A3,2} },
/*EV_DATA_BYTE_END*/ {{TX_A2,1} ,{TX_A4,3} }
};
void main(void) {
while(1)
{
(*TRANSMITER_TABLE[0][1].action)();//call the function of the transmiter table
}
}
void TX_A1(void)
{
}
void TX_A2(void)
{
}
void TX_A3(void)
{
}
void TX_A4(void)
{
}
-------------------------------------------------
-------------------------------------------------
Results:(from *.asm)
-------------------------------------------------
-------------------------------------------------
_main:
ar2 = 0x02
ar3 = 0x03
ar4 = 0x04
ar5 = 0x05
ar6 = 0x06
ar7 = 0x07
ar0 = 0x00
ar1 = 0x01
;main.c:44: while(1)
; [--------] ic:4: _whilebody_0($2) :
00102$:
;main.c:46: (*TRANSMITER_TABLE[0][1].action)();//call the function of the transmiter table
; [--------] ic:5: iTemp0 [k3 lr5:6 so:0]{ ia0 a2p0 re0 rm1 nos0 ru0 dp0}{const-struct Status_FT_12 [2] code-code* }[remat] = &[_TRANSMITER_TABLE [k2 lr0:0 so:0]{ ia0 a2p0 re0 rm0 nos0 ru0 dp0}{const-struct Status_FT_12 [2] code-[2] }]
; [--------] ic:6: iTemp1 [k4 lr6:7 so:0]{ ia0 a2p0 re0 rm1 nos0 ru0 dp0}{const-void function ( ) code* code-code* }[remat] = iTemp0 [k3 lr5:6 so:0]{ ia0 a2p0 re0 rm1 nos0 ru0 dp0}{const-struct Status_FT_12 [2] code-code* }[remat] + 0x3 {literal-unsigned-char}
; [--------] ic:7: iTemp3 [k7 lr7:8 so:0]{ ia0 a2p0 re0 rm0 nos0 ru0 dp0}{const-void function ( ) code-code* }[r2 r3 ] = @[iTemp1 [k4 lr6:7 so:0]{ ia1 a2p0 re0 rm1 nos0 ru0 dp0}{const-void function ( ) code* code-code* }[remat]]
; genPointerGet
; genCodePointerGet
mov dptr,#(_TRANSMITER_TABLE + 0x0003)
; Peephole 181 changed mov to clr
clr a
movc a,@a+dptr
mov r2,a
mov a,#0x01
movc a,@a+dptr
mov r3,a
; [--23----] ic:8: iTemp4 [k8 lr8:8 so:0]{ ia0 a2p0 re0 rm0 nos0 ru0 dp0}{code-const-void} = pcall iTemp3 [k7 lr7:8 so:0]{ ia0 a2p0 re0 rm0 nos0 ru0 dp0}{const-void function ( ) code-code* }[r2 r3 ]
; genPCall
push ar2
push ar3
mov a,#00107$
push acc
mov a,#(00107$ >> 8)
push acc
push ar2
push ar3
ret
-------------------------------------------------
-------------------------------------------------
In the assembler code I'm missing the jump order to the function pointer.
Is this a bug, or do I something wrong?
Thanks for your help
The last ret instruction does the call. If I read the code correctly, ar2 and ar3 contain the function pointer from the table. These are pushed into the stack just before ret is executed. Ret pops the return address off the stack and jumps there, in this case it will be address given by r2 and r3.