You are on page 1of 4

The following makefile was used to generate the hex record file for the example shown in class.

# Makefile demonstrating combination of C and assembly source files

mcdir=c:\\microc

# Note: 'm=2' option defines the compact memory model for mcc51
casm.asm : casm.c
$mcdir\\mcp $. $@.tmp -l l=$mcdir
$mcdir\\mcc51 $@.tmp $@.asm -l -c m=2

# Note: An external index file must be specified for slink using the 'i' option
prog.hex : casm.asm myasm.asm
$mcdir\\slink $. $@.asm l=$mcdir\\lib51 i=compact.lib
$mcdir\\asm51 $@ -fs

The following routines are utilized by the C compiler to manage internal and external memory pointers.

* Set up DPTR to access external stack


?accex1 MOV R6,#0 Assume high byte of zero
?accex2 XCH A,R7 Get LOW offset
ADD A,?stack Add to stack LOW
MOV DPL,A Save destination
MOV A,R6 Get HIGH Offset
ADDC A,?stack+1 Add to stack HIGH
MOV DPH,A Save destination
MOV A,R7 Restore ACC
RET

* Adjust external stack pointer by [R6:]R7 bytes


?adjex1 MOV R6,#0 Assume high of zero
?adjex2 XCH A,?stack Get LOW SP
ADD A,R7 Advance
XCH A,?stack Resave
XCH A,?stack+1 Get HIGH SP
ADDC A,R6 Include high
XCH A,?stack+1 And proceed
RET

* Setup R0 to access the stack


?auto0 XCH A,R0 Save A, get parameter
ADD A,SP Adjust for stack offset
XCH A,R0 And restore order
nargs RET

* Adjust the stack pointer by R7 bytes


?adjstk POP DPH Get high byte of RET addr
POP DPL Get low byte of RET addr
XCH A,R7 Get adjust (and save A)
ADD A,SP Adjust stack
MOV SP,A Set new value
XCH A,R7 Restore A (& return new stack)
PUSH DPL Resave low
PUSH DPH Resave high
RET

1
// casm.c
// C file showing parameter passing and interface between C and assembly
main()
{
//local variables are allocated on the external SRAM stack, referenced by ?stack
int ivar1, ivar2, ivar3, ivar4;
char cvar1, cvar2;

ivar1 = 5;
ivar2 = 8;
cvar1 = 1;
cvar2 = 2;

ivar3 = localfunction1 (ivar1, ivar2, cvar1);


ivar3 = localfunction2 (ivar1, ivar2);
ivar3 = externfunction3 (ivar1, ivar2, cvar1);
ivar4 = externfunction4 (ivar1, ivar2);
}
// localfunction1 returns the sum of the first two parameters
int localfunction1 (int param1, int param2, char param3)
{
char cvar3; //local variables are allocated on the external SRAM stack
cvar3 = param3;
return (param1 + param2);
}
// localfunction2 adds 1 to the first param, then adds second param and returns sum
int localfunction2 (int param1, int param2)
{
asm{
MOV R0,#-7 Offset in R0 is equal to -2n-3, where n is the number of arguments
LCALL ?auto0 Add offset in R0 to SP (SPs value after LCALL), store result in R0
MOV A,[R0] Get LSB of param1 from internal SRAM (IRAM)
INC R0 Increment internal SRAM pointer to point to MSB
MOV B,[R0] Get MSB of param1 from IRAM
INC R0 Increment IRAM pointer to point to LSB of param2
INC A Increment LSB of param1 by 1
JNZ *+4 If no overflow, skip over the next instruction
INC B Advance MSB of param1 by 1 if overflow occurred
ADD A,[R0] Get LSB of param2 from IRAM and add to param1 LSB
XCH A,B Swap MSB with LSB
INC R0 Increment IRAM pointer to point to MSB of param2
ADDC A,[R0] Get MSB of param2 and add to MSB of param1 with carry
XCH A,B Swap LSB with MSB. Now A contains LSB and B contains MSB of result.
}
}

2
*myasm.asm
*Assembly file showing parameter passing between C and assembly.

*This assembly function performs the same operation as localfunction2().


*Note that this function utilizes the ?auto function provided by MICRO-C.
*int externfunction3 (int param1, int param2, char cvar1)
externfunction3
MOV R0,#-9 Offset in R0 is equal to -2n-3, where n is the number of arguments
LCALL ?auto0 Add offset in R0 to SP (SP's value after LCALL); store result in R0
MOV A,[R0] Get LSB of param1 from internal SRAM (IRAM)
INC R0 Increment internal SRAM pointer to point to MSB
MOV B,[R0] Get MSB of param1 from IRAM
INC R0 Increment IRAM pointer to point to LSB of param2
INC A Increment LSB of param1 by 1
JNZ *+4 If no overflow, skip over the next instruction
INC B Advance MSB of param1 by 1 if overflow occurred
ADD A,[R0] Get LSB of param2 from IRAM and add to param1 LSB
XCH A,B Swap MSB with LSB
INC R0 Increment IRAM pointer to point to MSB of param2
ADDC A,[R0] Get MSB of param2 and add to MSB of param1 with carry
XCH A,B Swap LSB with MSB. Now A contains LSB and B contains MSB of result.
RET

*This assembly function performs the same operation as localfunction1().


*Note that this function does not rely on the ?auto function provided by MICRO-C.
*int externfunction4 (int param1, int param2)
externfunction4
MOV R0,#-5 Offset in R0 is equal to -2n-1, where n is the number of arguments
XCH A,R0 Save A, get parameter
ADD A,SP Adjust for stack offset
XCH A,R0 And restore order. R0 now points to the LSB of param1 on the stack.
MOV A,[R0] Get LSB of param1 from internal SRAM (IRAM)
INC R0 Increment internal SRAM pointer to point to MSB
MOV B,[R0] Get MSB of param1 from IRAM
INC R0 Increment IRAM pointer to point to LSB of param2
ADD A,[R0] Get LSB of param2 from IRAM and add to LSB of param1
XCH A,B Swap MSB with LSB
INC R0 Increment IRAM pointer to point to MSB of param2
ADDC A,[R0] Get MSB of param2 and add to MSB of param1 with carry
XCH A,B Swap LSB with MSB. Now A contains LSB and B contains MSB of result.
RET

3
The following figure shows the contents of external SRAM (?stack) after program execution completes.

DF90 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
DFA0 00 00 00 00 01 05 00 08 00 0E 00 0D 00 01 02 00
DFB0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

External SRAM [after main() completes; Note: no variables actually exist at that time]

Address Use Description Value after code execution


DFAFh Unused
DFAEh cvar2 char variable in main() 2
DFADh cvar1 char variable in main() 1
DFACh ivar4 MSB int variable in main() 00h
DFABh ivar4 LSB 0Dh
DFAAh ivar3 MSB int variable in main() 00h
DFA9h ivar3 LSB 0Eh
DFA8h ivar2 MSB int variable in main() 00h
DFA7h ivar2 LSB 08h
DFA6h ivar1 MSB int variable in main() 00h
DFA5h ivar1 LSB 05h
DFA4h cvar3 char variable in localfunction1() 01h
DFA3h Unused

Internal SRAM [after LCALL ?auto in localfunction2()]

Address Use Comment


12h Unused
SP→ 11h Return address MSB Return address pushed by LCALL ?auto
10h Return address LSB
0Fh Return address MSB Return address pushed by LCALL localfunction2
0Eh Return address LSB
0Dh ivar2 MSB Copy of ivar2 variable (param2)
0Ch ivar2 LSB
0Bh ivar1 MSB Copy of ivar1 variable (param1)
0Ah ivar1 LSB
09h ?stack MSB ?stack points to top of external stack
08h ?stack LSB
07h R7

You might also like