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)); }
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
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
32Func = 12345678 u32Func = 83d90e
Be sure to also report this direct to Keil support!
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.
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
Linker Bug confirmed No. You need to read the section in the Cx51 Compiler User's Guide about Language Extensions->Memory Types->Far. It contains the description of how "far" memory pointers are mapped on Dallas devices.