C51 Keil 问题

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wowocpp/article/details/83143263

C51: IS STARTUP.A51 REQUIRED?

http://www.keil.com/support/docs/1296.htm

QUESTION
I’m creating a project that is made up of C and assembly files. Do I need to use the STARTUP.A51 file that you provide, or can I use my own version?

ANSWER
We strongly urge you to use the STARTUP.A51 file that we provide as the basis for your startup routines. The Keil startup code performs the following operations:

Clears DATA and optionally PDATA and XDATA memory,
Sets up the reentrant stacks (if necessary)),
Initializes C Global Variables (see INIT.A51),
Sets the Stack Pointer (SP),
Jumps to your MAIN C function.
Your startup code must do all of these. If it doesn’t, you may encounter run-time problems that are difficult to debug and diagnose.

Note that if you do include some form of a startup file, Keil will automatically include a start up file that is in the Keil library.

C51: STACK POINTER INITIALIZATION IN STARTUP CODE

The stack pointer is initialized at the end of the C startup code in STARTUP.A51. Why is this necessary?

The last few lines of the startup code appear as follows:

IF PBPSTACK <> 0
EXTRN DATA (?C_PBP)
MOV ?C_PBP,#LOW PBPSTACKTOP
ENDIF

            MOV     SP,#?STACK-1
            LJMP    ?C_START

After reset, the stack pointer is initialized to 07h. The stack will start growing up from address 8h.

The Keil C compiler uses internal DATA memory for your variables and also allows you to use register banks 1, 2, and 3. If the stack pointer were not adjusted, calls to functions and interrupts would overwrite your variables.

Therefore, the last thing the startup code does is to set the stack pointer to the end of all your internal DATA variables.

C51: LOCATING THE STACK AFTER IDATA VARIABLES

I’m using some idata variables in my program. I want to make sure that the stack doesn’t overwrite them. What do I need to do?

The following example program declares variables as you describe:

int idata var1;
int idata var2;
int idata var3;

void main (void)
{
}
When compiled and linked, the following Link Map is generated in the MAP file output by the linker.

TYPE BASE LENGTH RELOCATION SEGMENT NAME

              • D A T A M E M O R Y * * * * * * *
                REG 0000H 0008H ABSOLUTE “REG BANK 0”
                IDATA 0008H 0006H UNIT ?ID?MAIN
                IDATA 000EH 0001H UNIT ?STACK
              • C O D E M E M O R Y * * * * * * *
                CODE 0000H 0003H ABSOLUTE
                CODE 0003H 000CH UNIT ?C_C51STARTUP
                CODE 000FH 0001H UNIT ?PR?MAIN?MAIN
                Note that the idata variables declared come before the stack. The stack on the 8051 grows up. Therefore, there is nothing you must do to avoid overwriting your idata variables.

C51 编译器,在 调用main函数之前会做以下操作:
在这里插入图片描述

Cx51 User’s Guide

http://www.keil.com/support/man/docs/c51/c51_library.htm

在这里插入图片描述

(稍后补充)

猜你喜欢

转载自blog.csdn.net/wowocpp/article/details/83143263