Keil Logo Arm Logo

LAST segment misplacement

Next Thread | Thread List | Previous Thread Start a Thread | Settings

Details Message
Read-Only
Author
Oleg Sergeev
Posted
24-Feb-2005 15:23 GMT
Toolset
None
New! LAST segment misplacement
hi,

according manual, when we need a segment to be placed at the end of specified memory we should use linker directive SEGMENTS. Well, in the field "User Segments" of LX51 Locate I have next string:
?PR?LAST(LAST)
Then next test program:
; reset vector --------------------------;
?PR?RESET	SEGMENT CODE AT 0x0000
		RSEG	?PR?RESET
		JMP	START
; timer 0 vector ------------------------;
?PR?T0INT	SEGMENT CODE AT 0x000B
		RSEG	?PR?T0INT
		JMP	T0INT

; work segment --------------------------;
?PR?TEST	SEGMENT CODE
		RSEG	?PR?TEST
START:		JMP	$
T0INT:		RETI

; last segment --------------------------;
?PR?LAST	SEGMENT CODE
		RSEG	?PR?LAST
		NOP

		END

produces next map file:
START     STOP      LENGTH    ALIGN  RELOC    MEMORY CLASS   SEGMENT NAME
=========================================================================
* * * * * * * * * * *   C O D E   M E M O R Y   * * * * * * * * * * * * *
000000H   000002H   000003H   BYTE   AT..     CODE           ?PR?RESET
000003H   000005H   000003H   BYTE   UNIT     CODE           ?PR?TEST
000006H   000006H   000001H   BYTE   UNIT     CODE           ?PR?LAST
000007H   00000AH   000004H   ---    ---      **GAP**
00000BH   00000DH   000003H   BYTE   AT..     CODE           ?PR?T0INT
And this is wrong because last segment named ?PR?LAST is not last one in the code space area.
But when I use next test program:
; reset vector --------------------------;
?PR?RESET	SEGMENT CODE AT 0x0000
		RSEG	?PR?RESET
		JMP	START
; timer 0 vector ------------------------;
		ORG	0x000B
		JMP	T0INT

; work segment --------------------------;
?PR?TEST	SEGMENT CODE
		RSEG	?PR?TEST

START:		JMP	$
T0INT:		RETI

; last segment --------------------------;
?PR?LAST	SEGMENT CODE
		RSEG	?PR?LAST
		NOP

		END
the MAP file shows correct results:
START     STOP      LENGTH    ALIGN  RELOC    MEMORY CLASS   SEGMENT NAME
=========================================================================
* * * * * * * * * * *   C O D E   M E M O R Y   * * * * * * * * * * * * *
000000H   00000DH   00000EH   BYTE   AT..     CODE           ?PR?RESET
00000EH   000010H   000003H   BYTE   UNIT     CODE           ?PR?TEST
000011H   000011H   000001H   BYTE   UNIT     CODE           ?PR?LAST

The only difference I see is that in the first case there is code gap in which linker has placed the last segment. Is there a way to avoid such behaviour?

Thanks,
Oleg
Read-Only
Author
Hans-Bernhard Broeker
Posted
24-Feb-2005 16:16 GMT
Toolset
None
New! RE: LAST segment misplacement
It could be documented a bit more exactly, but I don't agree this counts as a "misplacement" of the segment. It's quite reasonable that absolutely positioned segments are ignored when handling the LAST option. If it wasn't, the linker might well end up putting such a LAST segment beyond the end of memory, just because you put an absolute one that touches the ceiling.

There used to be (still is?) a real bug with LAST, though: if there's a gap in the middle of the sequence of relocatable segments (e.g. caused by the RESERVE directive), a LAST segment that fits there, could end up before the gap, even though there's more code located after it. We came across this when we RESERVEd some bytes close to the 64K boundaries of a DS390 to avoid hitting one of its errata. We ended up having to enlarge our LAST segment so it would no longer fit in the gap.

This IMHO made (makes?) LAST unusable for the main job it would appear to be meant for: defining a "code ends here" position for purposes of checksumming.
Read-Only
Author
Oleg Sergeev
Posted
25-Feb-2005 07:01 GMT
Toolset
C51
New! RE: LAST segment misplacement
hi,

Hans-Bernhard Broeker said:
>It's quite reasonable that absolutely positioned segments are ignored when handling the LAST option.

Maybe it is. And even we do not use absolute locations but just ask locator to align segments nevertheless result is the same:
; reset vector --------------------------;
?PR?RESET	SEGMENT CODE AT 0x0000
		RSEG	?PR?RESET
		JMP	START
; work segment --------------------------;
?PR?TEST	SEGMENT CODE PAGE
		RSEG	?PR?TEST
START:		JMP	$
; last segment --------------------------;
?PR?LAST	SEGMENT CODE
		RSEG	?PR?LAST
		NOP

		END
MAP file:
START     STOP      LENGTH    ALIGN  RELOC    MEMORY CLASS   SEGMENT NAME
=========================================================================
* * * * * * * * * * *   C O D E   M E M O R Y   * * * * * * * * * * * * *
000000H   000002H   000003H   BYTE   AT..     CODE           ?PR?RESET
000003H   000003H   000001H   BYTE   UNIT     CODE           ?PR?LAST
000004H   0000FFH   0000FCH   ---    ---      **GAP**
000100H   000101H   000002H   PAGE   UNIT     CODE           ?PR?TEST

>This IMHO made (makes?) LAST unusable for the main job it would appear to be meant for: defining a "code ends here" position for purposes of checksumming.

Yes, it is what we do here. As for now we have found a workaround - using ordering of segments without LAST keyword. For example, if for program above we use direct ordering with
?PR?*, ?PR?LAST
then MAP file shows correct results:
START     STOP      LENGTH    ALIGN  RELOC    MEMORY CLASS   SEGMENT NAME
=========================================================================
* * * * * * * * * * *   C O D E   M E M O R Y   * * * * * * * * * * * * *
000000H   000002H   000003H   BYTE   AT..     CODE           ?PR?RESET
000003H   0000FFH   0000FDH   ---    ---      **GAP**
000100H   000101H   000002H   PAGE   UNIT     CODE           ?PR?TEST
000102H   000102H   000001H   BYTE   UNIT     CODE           ?PR?LAST

Regards,
Oleg

Next Thread | Thread List | Previous Thread Start a Thread | Settings

Keil logo

Arm logo
Important information

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies.

Change Settings