This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Compiling through asm-source file. See any overlays?

I've found lots of differences between direct compiling from C and compiling through assembler! This differences are in the dealing with functions' arguments. for example:
When compiling directly from C, overlays are seems work, but in other way linker does not use any overlays, ignoring all "OVERLAYABLE" keywords in source file!

Sample C program:

void fun1(int a, int b,int c,int d) {
        a=b=c=d;
        return ;
}

void fun2(int a, int b, int c, int d) {
        c=a=b=d;
        //fun1(a,b,c,d);
        return ;
}

main() {
        fun1(0,0,0,0);
        fun2(0,0,0,0);
        while (1) ;
}

We'll got the following asm-source file:
; .\main.SRC generated from: main.c
; COMPILER INVOKED BY:
;        C:\Keil\C51\BIN\C51.EXE main.c OPTIMIZE(7,SPEED) REGFILE(.\test.ORC) NOINTPROMOTE NOPRINT SRC(.\main.SRC)


NAME	MAIN

?PR?_fun1?MAIN       SEGMENT CODE
?DT?_fun1?MAIN       SEGMENT DATA OVERLAYABLE
?PR?_fun2?MAIN       SEGMENT CODE
?DT?_fun2?MAIN       SEGMENT DATA OVERLAYABLE
?PR?main?MAIN        SEGMENT CODE
	EXTRN	CODE (?C_STARTUP)
	PUBLIC	main
	PUBLIC	?_fun2?BYTE
	PUBLIC	_fun2
	PUBLIC	?_fun1?BYTE
	PUBLIC	_fun1

	RSEG  ?DT?_fun1?MAIN
?_fun1?BYTE:
          a?040:   DS   2
          b?041:   DS   2
          c?042:   DS   2
          d?043:   DS   2

	RSEG  ?DT?_fun2?MAIN
?_fun2?BYTE:
          a?144:   DS   2
          b?145:   DS   2
          c?146:   DS   2
          d?147:   DS   2
; void fun1(int a, int b,int c,int d) {

	RSEG  ?PR?_fun1?MAIN
_fun1:
	USING	0
			; SOURCE LINE # 1
;---- Variable 'a?040' assigned to Register 'R6/R7' ----
;---- Variable 'c?042' assigned to Register 'R2/R3' ----
;---- Variable 'b?041' assigned to Register 'R4/R5' ----
;         a=b=c=d;
			; SOURCE LINE # 2
	MOV  	R6,d?043
	MOV  	R7,d?043+01H
	MOV  	R2,AR6
	MOV  	R3,AR7
	MOV  	R4,AR6
	MOV  	R5,AR7
;         return ;
; }
			; SOURCE LINE # 4
?C0001:
	RET
; END OF _fun1

;
; void fun2(int a, int b, int c, int d) {

	RSEG  ?PR?_fun2?MAIN
_fun2:
	USING	0
			; SOURCE LINE # 6
;---- Variable 'a?144' assigned to Register 'R6/R7' ----
;---- Variable 'c?146' assigned to Register 'R2/R3' ----
;---- Variable 'b?145' assigned to Register 'R4/R5' ----
;         c=a=b=d;
			; SOURCE LINE # 7
	MOV  	R6,d?147
	MOV  	R7,d?147+01H
	MOV  	R4,AR6
	MOV  	R5,AR7
	MOV  	R2,AR4
	MOV  	R3,AR5
;         //fun1(a,b,c,d);
;         return ;
; }
			; SOURCE LINE # 10
?C0002:
	RET
; END OF _fun2

;
; main() {

	RSEG  ?PR?main?MAIN
main:
	USING	0
			; SOURCE LINE # 12
;         fun1(0,0,0,0);
			; SOURCE LINE # 13
	CLR  	A
	MOV  	?_fun1?BYTE+06H,A
	MOV  	?_fun1?BYTE+07H,A
	MOV  	R3,A
	MOV  	R2,A
	MOV  	R5,A
	MOV  	R4,A
	MOV  	R7,A
	MOV  	R6,A
	LCALL	_fun1
;         fun2(0,0,0,0);
			; SOURCE LINE # 14
	MOV  	?_fun2?BYTE+06H,A
	MOV  	?_fun2?BYTE+07H,A
	MOV  	R3,A
	MOV  	R2,A
	MOV  	R5,A
	MOV  	R4,A
	MOV  	R7,A
	MOV  	R6,A
	LCALL	_fun2
?C0003:
;         while (1) ;
			; SOURCE LINE # 15
	SJMP 	?C0003
	RET
; END OF main

	END

OK, let's look what we got after linking:
.obj file obtained directly from C:
LINK MAP OF MODULE:  test (MAIN)


            TYPE    BASE      LENGTH    RELOCATION   SEGMENT NAME
            -----------------------------------------------------

            * * * * * * *   D A T A   M E M O R Y   * * * * * * *
            REG     0000H     0008H     ABSOLUTE     "REG BANK 0"
            DATA    0008H     0008H     UNIT         _DATA_GROUP_
            IDATA   0010H     0001H     UNIT         ?STACK

            * * * * * * *   C O D E   M E M O R Y   * * * * * * *
            CODE    0000H     0003H     ABSOLUTE
            CODE    0003H     001EH     UNIT         ?PR?MAIN?MAIN
            CODE    0021H     000DH     UNIT         ?PR?_FUN1?MAIN
            CODE    002EH     000DH     UNIT         ?PR?_FUN2?MAIN
            CODE    003BH     000CH     UNIT         ?C_C51STARTUP



OVERLAY MAP OF MODULE:   test (MAIN)


SEGMENT                          DATA_GROUP
  +--> CALLED SEGMENT          START    LENGTH
----------------------------------------------
?C_C51STARTUP                  -----    -----
  +--> ?PR?MAIN?MAIN

?PR?MAIN?MAIN                  -----    -----
  +--> ?PR?_FUN1?MAIN
  +--> ?PR?_FUN2?MAIN

?PR?_FUN1?MAIN                 0008H    0008H

?PR?_FUN2?MAIN                 0008H    0008H

everything is great, isn't it?

But what we'll got from .obj file obtained from asm-file? We'll got this: (!)
LINK MAP OF MODULE:  test (MAIN)


            TYPE    BASE      LENGTH    RELOCATION   SEGMENT NAME
            -----------------------------------------------------

            * * * * * * *   D A T A   M E M O R Y   * * * * * * *
            REG     0000H     0008H     ABSOLUTE     "REG BANK 0"
            DATA    0008H     0008H     UNIT         ?DT?_FUN1?MAIN
            DATA    0010H     0008H     UNIT         ?DT?_FUN2?MAIN
            IDATA   0018H     0001H     UNIT         ?STACK

            * * * * * * *   C O D E   M E M O R Y   * * * * * * *
            CODE    0000H     0003H     ABSOLUTE
            CODE    0003H     001EH     UNIT         ?PR?MAIN?MAIN
            CODE    0021H     000DH     UNIT         ?PR?_FUN1?MAIN
            CODE    002EH     000DH     UNIT         ?PR?_FUN2?MAIN
            CODE    003BH     000CH     UNIT         ?C_C51STARTUP

No overlays at all!
Isn't it a memory wasting?

  • Well, as the saying goes: don't do that, then! In the case at hand, there's no particular need at all to compile through an intermediate asm source, so don't do it, and all will be well.

    Longer explanation follows:

    Compilers can be designed so it makes no difference at all whether you go through assembler or not (typically by always going through an intermediate assembler source file) --- but Keil C51 is not designed that way. The core reason for all this is that Ax51 can't output the same amount of auxiliary information to object files as Cx51: no source debug info, and apparently no overlay steering information either.

    I personally consider this state of affairs a serious weakness, but since this doesn't appear likely to change any time soon, the following advice remains valid:

    *) Don't use SRC mode unless you absolutely have to
    *) If you think you have to use assembly language, do so in a separate assembly source file.
    *) SRC mode is useful for generating a template for such an assembly source file, but not for much more.

  • Hmmm,

    The segments are declared correctly:

    ?DT?_fun1?MAIN SEGMENT DATA OVERLAYABLE

    What version of the tools are you using?

    Jon

  • The setup for Data Overlaying and Code Banking with A51 Assembler Modules is discussed in:
    http://www.keil.com/appnotes/docs/apnt_149.asp

  • Cite from this .pdf:
    "NOTES
    The BL51 linker/locater enables data overlaying and code banking only if at least one object module is
    generated by the C51 Compiler. Therefore your project should contain on C51 source file that is
    directly translated to an object file with the C51 compiler. In case that you do not have any C sources,
    you may translate an empty file with C51.
    "


    Isn't it a solution of my problem? Ofcourse yes!
    Thanx, Oliver!