We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
Hi I am unclear as to how I can pass 2 generic pointer arguments into a function. As stated in the user guide, the generic ptr will be stored in R1-R3. But however, what happens when there is more than 1 argument? Please advice. Any explaination is appreciated. Thank you in advance. Regards Wtwh
Any parameters that don't fit into registers spill over into overlayable memory addresses, somewhat like auto variables. From the manual: Parameter Passing in Fixed Memory Locations Parameters passed to assembly routines in fixed memory locations use segments named ?function_name?BYTE and ?function_name?BIT to hold the parameter values passed to the function function_name. Bit parameters are copied into the ?function_name?BIT segment prior to calling the function. All other parameters are copied into the ?function_name?BYTE segment. All parameters are assigned space in these segments even if they are passed using registers. Parameters are stored in the order in which they are declared in each respective segment. The fixed memory locations used for parameter passing may be in internal data memory or external data memory depending upon the memory model used. The SMALL memory model is the most efficient and uses internal data memory for parameter segments. The COMPACT and LARGE models use external data memory for the parameter passing segments. -- Hence my wish for a "medium" memory model that will keep extra parameters and temps in data rather than xdata by default, even while globals go in xdata.
Hence my wish for a "medium" memory model that will keep extra parameters and temps in data rather than xdata by default, even while globals go in xdata Why not use a model that 'keep extra parameters and temps in data' and use the xdata modifier in your global definitions. Erik
Convenience. A memory model with the Keil compiler is just a convenience, since you can easily override the implicit locations, as you point out. Of course, I have some sympathy for the claims that you shouldn't trust to the memory model at all, but explicitly specify the location of all your data items. It could certainly save some pain if you did have to switch memory models at some point, or had to port your code to another system. This particular wish is fairly far down my list, as it happens. But I have caught myself wishing, when running around and hand-tuning the code by putting in "data" and "xdata" here and there. (Yes, I did actually #define a macro for them. Not that it'll actually help if I have to switch to a #pragma-style compiler.)
Thank you for your responses. I have a follow up question regarding parameter passing in fixed memory locations. As mentioned, I understand that the second generic pointer is passed using segment name function?byte. However, I still do not know how I can access the values passed in. I tried : mov DPTR,#?_FUNCTION?BYTE+0 but it doesn't work. Could you kindly advise? Any reference to sample code would be most useful. Thank you.
There can - as far as I can see - be no reason for your question other than calling an assembler routine from C. The easy way to code that is to make a skeleton routine in C and use the very well documented assembly code generated as a template. Erik
The easy way to code that is to make a skeleton routine in C and use the very well documented assembly code generated as a template. Like you said,I have tried what you suggested. Unfortunately, I still have difficulty making sense of the assembly output. For example, to access a parameter it uses MOV DPTR,#ptos which I tried but generated an error in my assembly function. Kindly advice. Thank you very much.
I'm not sure from your response if you tried "?function?byte" literally. You need to substitute the name of the actual function for function. (Each function could potentially have its own parameter area; when the functions are not declared reentrant, the linker will overlay these areas according to the call tree.) Check carefully the size and number of your parameters so that you can figure out the right offset in the ?_MyFunction?byte area to find your parameter. Note that you can pass up to three two-byte pointers in registers. If you're willing to restrict the function to work only on xdata (for example), you might be able to avoid parameters spilling into memory.
Thank you for the reply. Yes. I did substitute the name of the function. 1) The first parameter passed in is actually an address &array[10] while the variable array is declared in xdata. However, the values are still found in R1-R3 instead of R6-R7. How can I make it a 2-byte pointer? 2)The second parameter is a function pointer. In this case how can work on xdata with this parameter? The actual value passed in is the name of the function. Thank you for your advice. Although seemingly straight-forward, I'm having problems access the values passed in from the allocated memory location.
How can I make it a 2-byte pointer? I do not know, try typecastion it a short. Unfortunately Keil has given in to the PC types that believe that the '51 is just another processor. Anyone coding for the '51 that want to be unaware of which codespace a variable is located in should go back to his/her beloved PC. Erik
How can I make it a 2-byte pointer Your type declarations must include one of the memory type qualifers, e.g. void MyFunction (U8 xdata* p1, U8 xdata* p2) instead of void MyFunction (U8* p1, U8* p2) The first has a two-byte pointers passed in R6/R7 and R4/R5, the second is a three-byte generic pointer passed in R1-R3 and some memory space. The advantage of the second format is that one routine will work on data in any location (data or xdata). The first produces smaller and faster code.