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

indirect call

Hello

I have a function like this :

static int yaffs_WriteChunkToNAND(struct yaffs_DeviceStruct *dev,int chunkInNAND, const __u8 *data, yaffs_Spare *spare)
{
        .
         .
         .
return dev->writeChunkToNAN(dev,chunkInNAND ,data,spare);
}

dev is a struct like this:

struct yaffs_DeviceStruct
{
int   nBytesPerChunk;
int (*writeChunkToNAND)(struct yaffs_DeviceStruct *dev,int chunkInNAND, const __u8 *data, yaffs_Spare *spare);
int (*readChunkFromNAND)(struct yaffs_DeviceStruct *dev,int chunkInNAND, __u8 *_data, yaffs_Spare *spare);

but when compile this code, there is an error like this:
indirect call: parameters do not fit within registers.

What is couse of thiss error and what is solution?

Parents
  • Alas, the manual section is down, but in short, '51 code seldom makes use of indirect function calls, because of a bit of problems with the processor instruction set.

    The compiler has a "normal" way of passing parameters, and in this case it needs a number of registers for the parameters to the function.

    Since you call the function indirectly, the compiler needs extra registers to handle the function pointer. The processor has a limited number of registers and in this case gets into trouble.

    You have to check in the manual which attributes you can add to a function prototype to affect how parameters are sent to it.

    If you can't affect the calling convention for the function, then you will have to change it's signature to take fewer parameters. For example by sending a pointer to a struct.

Reply
  • Alas, the manual section is down, but in short, '51 code seldom makes use of indirect function calls, because of a bit of problems with the processor instruction set.

    The compiler has a "normal" way of passing parameters, and in this case it needs a number of registers for the parameters to the function.

    Since you call the function indirectly, the compiler needs extra registers to handle the function pointer. The processor has a limited number of registers and in this case gets into trouble.

    You have to check in the manual which attributes you can add to a function prototype to affect how parameters are sent to it.

    If you can't affect the calling convention for the function, then you will have to change it's signature to take fewer parameters. For example by sending a pointer to a struct.

Children
  • One of the restrictions on function pointers in Keil C is that the parameters must be able to be passed in registers. The manual will give you details on the calling conventions, but in short: no more than three params, 16 bits or less; one 32-bit value; and possibly one 24-bit pointer (far or generic).

    The example function has four parameters, and so there's no way to fit them all into registers.

    When Keil C spills parameters out of registers, it has to allocate specific places in memory to hold the extras. These would have to be the same addresses for every function that could be called through a function pointer (which might also be called normally, and thus wind up in simultaneously yet another place in another call tree), and the compiler just can't handle that much complexity.

    You can declare your functions to be called via pointer as reentrant, which means parameters passed on the "software stack", and thus avoid this problem.

    You should read app note 129 on function pointers:
    http://www.keil.com/appnotes/docs/apnt_129.asp

  • the simple way would be to drop the function pointer and replace it with
    if (xxx) hhh();

    if you absolutely have to make the compiler try to do something the architecture was never intended for, then, instead of passing some/one of the parameters store itthem in (a) global variables.

    i personally, would never do anyrthing but the first suggestion.

    Erik

  • ive just got my xml parser running over here and that has lots of indirection.
    beets the pants off the .net stuff.