Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
39
Добавлен:
14.04.2015
Размер:
301.71 Кб
Скачать

RAM Locations

Used:

 

 

D:0012H

SYMBOL

tex

// execute’s locals overlap

D:0013H

SYMBOL

arrex

// func4 and func5’s - OK

D:000FH

SYMBOL

y

 

D:0010H

SYMBOL

arr4

 

D:000FH

SYMBOL

y5

 

D:0010H

SYMBOL

arr5

 

Incidentally, the overlay map shows which functions referred to which other functions. By checking what L51 has found against what you expect, overlay hazards may be spotted.

8.4.2.2 Indirectly called functions solution

Use the overlay command when linking thus:

main.obj & to exec.abs & OVERLAY(main ; (func4,func5), _execute ! (func4,func5))

Note: The tilde sign ‘;’ means: “Ignore the reference to func4/5 from main” The ‘!’ means: “Manually generate a reference between intermediate function ‘execute’ and func4/5 to prevent overlaying of local variables within these functions.”

Please make sure you understand exactly how this works!!!

The new linker output is:

MS-DOS MCS-51 LINKER /

LOCATER

L51

V2.8,

INVOKED BY:

L51 MAIN.OBJ TO EXEC.ABS OVERLAY(MAIN ;(FUNC4, FUNC5), _EXECUTE ! (FUNC4, FUNC5))

OVERLAY

MAP

OF MODULE:

EXEC.ABS (MAIN)

 

SEGMENT

 

 

 

DATA-GROUP

+—> CALLED

SEGMENT

START

 

LENGTH

 

?C_C51STARTUP

 

 

 

 

+—>

?PR?MAIN?MAIN

 

 

 

 

?PR?MAIN?MAIN

 

0024H

0001H

+—> ?PR?FUNC1?MAIN

 

 

 

 

+—> ?PR?FUNC2?MAIN

 

 

 

 

+—> ?PR?FUNC3?MAIN

 

 

 

 

+—> ?PR?_EXECUTE?MAIN

 

 

 

 

?PR?FUNC1?MAIN

 

0025H

000BH

?PR?FUNC2?MAIN

 

0025H

000BH

?PR?FUNC3?MAIN

 

0025H

000BH

?PR?_EXECUTE?MAIN

 

0025H

000EH

+—> ?C_LIB_CODE

 

 

D:0028H

SYMBOL

tex

// Execute’s variables

 

 

 

no longer

D:0029H

SYMBOL

arrex

// overlaid with func4/

 

 

 

5’s

D:0008H

SYMBOL

y

 

D:0009H

SYMBOL

arr4

 

D:0013H

SYMBOL

y5

 

D:0014H

SYMBOL

arr5

 

***WARNING 16: UNCALLED SEGMENT,IGNORED FOR OVERLAY PROCESS SEGMENT: ?PR?FUNC4?MAIN

***WARNING 16: UNCALLED SEGMENT,IGNORED FOR OVERLAY PROCESS SEGMENT: ?PR?FUNC5?MAIN

© Copyright Hitex (UK) Ltd. 1996

C51 Primer page 65

Note: The WARNING 16’s show that func4/5 have been removed from the overlay process to remove the hazard. See section 8.4.2.6 on the “UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS” warning.

8.4.2.3 Function Jump Table Warning (Non-hazardous)

Here two functions are called an array of function pointers. The array “jump_table” exists in a segment called “?CO?MAIN1, i.e. the constant area assigned to module main. The problem arises that the two message string arguments to the printf ’s are also sited here. This leads to a recursive definition of the function start addresses in the jump table.

While this is not in itself dangerous, it prevents the real function references from being established and hence the overlaying process is inhibited.

****************************************************************************;

*<<<<<<<<<<<<<Recursive Call To Segment Error>>>>>>>>>>>>>>*

****************************************************************************;

#include <stdio.h> #include <reg517.h>

void func1(void) {

unsigned char i1 ;

for(i1 = 0 ; i1 < 10 ; i1++) {

printf(“THIS IS FUNCTION 1\n”) ; // String stored in ?CO?MAIN1 segment

}

}

void func2(void) {

unsigned char i2 ;

for(i2 = 0 ; i2 < 10 ; i2++) {

printf(“THIS IS FUNCTION 2\n”) ; // String stored in ?CO?MAIN1 segment

}

}

code void(*jump_table[])()={func1,func2}; //Jump table to functions,

//table stored in ?CO?MAIN1

//segment.

/*** Calling Function ***/

main() {

 

(*jump_table[P1 & 0x01])() ;

// Call function via jump

 

table in ?CO?MAIN1

}

^^^^^^^^^^^^^^^^^^^^^^^ End of Module

The resulting link output is:

Note: No reference exists between main and func1/2 so the overlay process cannot occur, resulting in wasted

 

 

 

 

RAM.

 

OVERLAY

MAP OF MODULE:

MAIN1 (MAIN1)

 

 

SEGMENT

 

BIT-GROUP

DATA-GROUP

+—> CALLED SEGMENT

START

LENGTH

START

LENGTH

?C_C51STARTUP

+—> ?PR?MAIN?MAIN1

?PR?MAIN?MAIN1 +—> ?CO?MAIN1 +—> ?C_LIB_CODE

© Copyright Hitex (UK) Ltd. 1996

C51 Primer page 66

?CO?MAIN1

 

 

 

 

+—>

?PR?FUNC1?MAIN1

 

 

 

+—>

?PR?FUNC2?MAIN1

 

 

 

?PR?FUNC1?MAIN1

 

 

0008H

0001H

+—>

?PR?PRINTF?PRINTF

 

 

 

MCS-51 LINKER / LOCATER

L51 V2.8

 

 

DATE

04/08/92

PAGE

2

 

 

?PR?PRINTF?PRINTF

 

0020H.0 0001H.1

0009H

0014H

+—>

?C_LIB_CODE

 

 

 

 

+—>

?PR?PUTCHAR?PUTCHAR

 

 

?PR?FUNC2?MAIN1

 

 

0008H

0001H

+—>

?PR?PRINTF?PRINTF

 

 

 

***WARNING 13: RECURSIVE CALL TO SEGMENT SEGMENT: ?CO?MAIN1

CALLER: ?PR?FUNC1?MAIN1

***WARNING 13: RECURSIVE CALL TO SEGMENT SEGMENT: ?CO?MAIN1

CALLER: ?PR?FUNC2?MAIN1

8.4.2.4 Function Jump Table Warning Solution

The solution is to use the OVERLAY command when linking thus:

main1.obj & to main1.abs &

OVERLAY(?CO?MAIN1 ~ (func1,func2), main ! (func1,func2))

This deletes the reference to func1 & 2 from the ?CO?MAIN1 segment and inserts the true reference from main to func1 & func2.

The linker output is now thus:

OVERLAY MAP OF MODULE: MAIN1.ABS (MAIN1)

 

 

SEGMENT

BIT-GROUP

DATA-GROUP

+—>

CALLED SEGMENT

START

LENGTH

START

LENGTH

?C_C51STARTUP

 

 

 

 

+—>

?PR?MAIN?MAIN1

 

 

 

 

?PR?MAIN?MAIN1 +—> ?CO?MAIN1 +—> ?C_LIB_CODE

+—> ?PR?FUNC1?MAIN1 +—> ?PR?FUNC2?MAIN1

?PR?FUNC1?MAIN1

 

0008H

0001H

+—> ?CO?MAIN1

 

 

 

+—> ?PR?PRINTF?PRINTF

 

 

?PR?PRINTF?PRINTF

0020H.0 0001H.1

0009H

0014H

+—> ?C_LIB_CODE

 

 

 

+—> ?PR?PUTCHAR?PUTCHAR

 

 

?PR?FUNC2?MAIN1

 

0008H

0001H

+—> ?CO?MAIN1

 

 

 

+—> ?PR?PRINTF?PRINTF

 

 

© Copyright Hitex (UK) Ltd. 1996

C51 Primer page 67

8.4.2.5 Multiple Call To Segment Warning (Hazardous)

This warning generally occurs when a function is called from both the background and an interrupt. This means that potentially the interrupt may call the function whilst it is still running, as a result of a background level call. The result could be the over-writing of the local data in the background. The fact that the offending function is also overlaid with other background functions makes the chances of failure very high. The simplest solution is to declare the function as REENTRANT so that the compiler will generate a local stack for parameters and variables. Thus on each call to the function, a new set of parameters and local variables are created without destroying any existing ones from the current call.

Unfortunately this significantly increases the run time and code produced. Another possibility is to make a second and renamed version of the function, one for background use and one for interrupt. This is somewhat wasteful and presents a maintenance problem, as you now have effectively two versions of the same piece of code.

In many cases the situation is not a problem, as the user may have ensured that the reentrant use could never occur, but is left with the linker warning. However this must be viewed as dangerous, particularly if more than one programmer is involved.

#include <stdio.h> #include <reg517.h>

void func1(void) {

unsigned char i1,a1[15] ;

for(i1 = 0 ; i1 < 10 ; i1++) {

a1[i1] = i1 ;

}

}

void func2(void) {

unsigned char i2,a2[15] ;

for(i2 = 0 ; i2 < 10 ; i2++) {

a2[15] = i2 ;

}

}

main() { func1() ; func2() ;

}

void timer0_int(void) interrupt 1 { func1() ;

} ^^^^^^^^^^^^^^^^^^^^^^^ End of Module

This produces the linker

map:

 

OVERLAY MAP OF MODULE:

MAIN2 (MAIN2)

 

SEGMENT

DATA-GROUP

+—> CALLED SEGMENT

START

LENGTH

?PR?TIMER0_INT?MAIN2

 

 

+—> ?PR?FUNC1?MAIN2

 

 

?PR?FUNC1?MAIN2

0017H

000FH

?C_C51STARTUP

 

 

+—> ?PR?MAIN?MAIN2

 

 

?PR?MAIN?MAIN2

 

 

+—> ?PR?FUNC1?MAIN2

 

 

+—> ?PR?FUNC2?MAIN2

 

 

?PR?FUNC2?MAIN2

0017H

000FH

© Copyright Hitex (UK) Ltd. 1996

C51 Primer page 68

Соседние файлы в папке Keil_51_v750a_OK_work