From: Joris v. d. S. <vd...@pu...> - 2001-02-15 21:10:25
|
Hi Rod, Sorry, let me emphasize that I am not trying to criticise you, I am just trying to make sure people get the right idea about reentrancy... >> int FnDivide( int param1, int param2 ) >> { >> return( param1 / param2 ); >> } > > I believe I used this as an example to describe a re-entrant > function. I can assure you that on any stack based system > (not the 8051) this function would be re-entrant like I said > in the following text this probably will not work with the > SDCC (or the Keil compiler for that matter) on the 8051. In fact, on a stack-based system _any_ function is reentrancy- safe! Therefore, your example doesn't illustrate much, as you could have shown _any_ arbitrary function! I can only repeat myself: a compiler that generates non-stack- based code (for example SDCC), will use fixed memory locations to store local variables. A compiler that uses the stack will simply allocate room on the stack for local variables and will therefore be automatically reentrant. The SDCC compiler however, needs to be told when it should use the stack for allocating local variables, by specifying the `reentrant' keyword. Perhaps you were trying to illustrate reentrant code (contrary to reentrancy-safe code). Then you could show a function that calls itself, for example: int fac(int n) reentrant { if (n == 1) { return 1 ; } else { return n * fac(n-1) ; } } > PS I haven't touch an 8051 for about 18 months now. I am > mainly working on embedded PowerPC & 68HC11 chips these days > (new job new processor). Good for you! Must be a great relieve to jump from an ancient 8-bit processor with segmented memory and a tiny stack to a huge, fast 32-bit PowerPC! Even the 68HC11, although being just 8-bit, is much easier to handle with its nice linear memory... ...why was I using the 8051 again? :-) Regards, Joris P.S. Just to be complete, here is a quote from the relevant chapter in the SDCC manual: > Automatic (local) variables and parameters to functions can > either be placed on the stack or in data-space. The default > action of the compiler is to place these variables in the > internal RAM ( for small model) or external RAM (for Large > model). They can be placed on the stack either by using the > --stack-auto compiler option or by using the 'reentrant' > keyword in the function declaration. > > eg > > unsigned short foo( short i) reentrant { > ... > } > > > Note that when the parameters & local variables are declared > in the internal/external ram the functions are non-reentrant. > Since stack space on 8051 is limited the 'reentrant' keyword > or the --stack-auto option should be used sparingly. Note the > reentrant keyword just means that the parameters & local > variables will be allocated to the stack, it DOES NOT mean > that the function is register bank independent. > > When compiled with the default option (i.e. non-reentrant ), > local variables can be assigned storage classes and absolute > addresses. > > eg > > > unsigned short foo() { > xdata unsigned short i; > bit bvar; > > data at 0x31 unsiged short j; > ... > } > > > In the above example the variable i will be allocated in the > external ram, bvar in bit addressable space and j in internal > ram. When compiled with the --stack-auto or when a function > is declared as 'reentrant' local variables cannot be assigned > storage classes or absolute addresses. > > Parameters however are not allowed any storage class, > (storage classes for parameters will be ignored), their > allocation is governed by the memory model in use , and the > reentrancy options. |