|
Read-Only
Author Lucas Lin
Posted 24-Mar-2006 07:50 GMT
Toolset C51
|
 function pointers in Dallas 390 contiguous mode
Lucas Lin
I was struggling with the function pointer in Dallas 390 contiguous mode. It seems that the linker might not relocate the correct address in function pointer. Check the following code:
void Test(void)
{
UINT32 u32Tmp;
u32Tmp = 0x12345678ul;
TASK_PRN(("u32Func = %lx\n", u32Tmp));
u32Tmp = Test;
TASK_PRN(("u32Func = %lx\n", u32Tmp));
}
The Linker generate the address for Test: Test function is located at 2D90EH. 02D90EH 02D957H 00004AH BYTE INSEG ECODE ?PR?TEST?TASK The TASK_PRN macro calls my own written printf utility. Here is the output: u32Func = 12345678 u32Func = 83d90e I couldn't figure out why is this happening. Keil C version : C Compiler : C51.Exe V7.20 Assembler: AX51.Exe V2.13 Linker/Locator: LX51.Exe V3.64 Librian: LIBX51.Exe V4.24 C compiler Setting: LARGE OMF2 ROM(D16M) OPTIMIZE (SIZE) BROWSE ORDER MODDP2 Any body encounter this problem ? Thanks in advance! Lucas
|
|
Read-Only
Author Lucas Lin
Posted 24-Mar-2006 08:35 GMT
Toolset C51
|
 RE: function pointers in Dallas 390 contiguous mode
Lucas Lin
Linker Bug confirmed
I've checked the assembly listing and the generated binary code. And I found that the linker does not give correct relocation address in instruction relocation record.
assembly listing
; FUNCTION Test (BEGIN)
; SOURCE LINE # 246
; SOURCE LINE # 247
; SOURCE LINE # 250
0000 7F78 MOV R7,#078H
0002 7E56 MOV R6,#056H
0004 7D34 MOV R5,#034H
0006 7C12 MOV R4,#012H
;---- Variable 'u32Tmp' assigned to Register 'R4/R5/R6/R7' ----
; SOURCE LINE # 251
0008 7B00 R MOV R3,#MBYTE ?SC_117
000A 7A00 R MOV R2,#HIGH ?SC_117
000C 7900 R MOV R1,#LOW ?SC_117
000E 90000000 E MOV DPTR,#?UART_iPrintk?BYTE
0012 12000000 E LCALL ?C?PSTXDATA
0016 90000000 E MOV DPTR,#?UART_iPrintk?BYTE+03H
001A 12000000 E LCALL ?C?LSTXDATA
001E 12000000 E LCALL UART_iPrintk
; SOURCE LINE # 252
0022 7B00 R MOV R3,#MBYTE Test
0024 7A00 R MOV R2,#HIGH Test
0026 7900 R MOV R1,#LOW Test
0028 AF01 MOV R7,AR1
002A AE02 MOV R6,AR2
002C AD03 MOV R5,AR3
002E 7C00 MOV R4,#00H
Binary Code
1D90E: 7F 78 ; MOV R7 , #078H
1D910: 7E 56 ; MOV R6, #056H
....
1D930: 7B 83 ; MOV R3, #083H
1D932: 7A D9 ; MOV R2, #0D9H
1D934: 79 0E ; MOV R1, #00EH
That's why I get the strange results:
32Func = 12345678
u32Func = 83d90e
|
|
Read-Only
Author Hans-Bernhard Broeker
Posted 24-Mar-2006 17:13 GMT
Toolset C51
|
 RE: function pointers in Dallas 390 contiguous mode
Hans-Bernhard Broeker
The bug is in your expectations, not in the linker. What on earth made you assume you knew what the result of casting a pointer to an integer was, better than the tools that actually use those pointers? Do you know what terms like "undefined behaviour" or "unspecified result" mean?
Not only is your expectation unfounded, it actually contradicts the documented behaviour, too.
|
|
Read-Only
Author Jon Ward
Posted 24-Mar-2006 17:51 GMT
Toolset C51
|
 RE: function pointers in Dallas 390 contiguous mode
Jon Ward
Refer to the following KB article: http://www.keil.com/support/docs/2226.htm
And to the description for far pointers in the C51 Manual:
http://www.keil.com/support/man/docs/c51/c51_le_far.htm
Based on this information and the address of your function
(2D90EH), I would conclude that the far pointer to the function
should contain 0x83D90E.
Jon
|