error C212: indirect call: parameters do not fit within registers

转自: http://www.keil.com/support/docs/2066.htm

Information in this article applies to:

  • C51 All Versions
  • Cx51 All Versions

SYMPTOMS

I'm using function pointers and object-oriented programming techniques in my application. Most of the time my program works as expected. But when I try to pass several parameters to functions that are called via pointers, I get the following compiler error message:

Error 212: Indirect call: Parameters do not fit within registers.

The program example below demonstrates this:

void (*CallBack1) (void *, unsigned char);
void (*CallBack2) (void *, void *);
void (*CallBack3) (char, char, char);
void (*CallBack4) (char, char, char, char);

unsigned char  c, d, e, f;
         char *ptr;

void test (void) {

  CallBack1 (ptr, c);     // works
  CallBack2 (ptr, ptr);   // fails - C51 generates an error message
                          // indirect call: parameters do not fit within
registers */

  CallBack3 (c, d, e);    // works
  CallBack4 (c, d, e, f); // fails - C51 generates an error message
                          // indirect call: parameters do not fit within
registers */
}

CAUSE

Unlike most 16-bit and 32-bit microcontrollers, the 8051 is not a stack based architecture. When parameters do not fit into the CPU registers, the Keil Cx51 Compiler by default uses direct memory locations for parameter passing. This technique generates very efficient code but limits the parameters that can be passed to indirectly called functions. When parameters passed to a function via a function pointer will not fit into registers, the compiler cannot determine where in memory to place the parameters since the function is not known at call-time.

RESOLUTION

There are two ways to solve your programming problem.

  1. Create reentrant functions using the reentrant function attribute. The compiler simulates a stack-based architecture which makes it possible to pass a virtually unlimited number of parameters to indirectly called functions. For example:
    void (*CallBack1) (void *, unsigned char);
    void (*CallBack2) (void *, void *)         reentrant;
    void (*CallBack3) (char, char, char);
    void (*CallBack4) (char, char, char, char) reentrant;
    
    unsigned char  c, d, e, f;
             char *ptr;
    
    void test (void) {
    
      CallBack1 (ptr, c);     // works
      CallBack2 (ptr, ptr);   // works, but now the function that gets called
                              // need to have the reentrant attribute
      CallBack3 (c, d, e);    // works
      CallBack4 (c, d, e, f); // works, but now the function that gets called
                              // need to have the reentrant attribute
    }
    
  2. Limit the number and types of parameters so that they all fit into CPU registers. Do this when you need utmost performance or when program size is critical. For example:
    void (*CallBack1) (void *, unsigned char);
    void (*CallBack2) (void xdata *, void xdata *);
    void (*CallBack3) (char, char, char);
    void (*CallBack4) (char, char, int);
    
    
    unsigned char  c, d, e, f;
             char xdata *ptr;
    
    
    void test (void) {
    
    
      CallBack1 (ptr, c);     // works
      CallBack2 (ptr, ptr);   // works, but pointers are memory typed now
    
    
      CallBack3 (c, d, e);    // works
      CallBack4 (c, d, e | (f<<8)); // works, but two chars are packed into
                              // one int parameter
    }
    
    The parameter passing method is described in the C51/Cx51 Compiler User's Guide. Refer to this to determine how to change your function parameters to fit into registers.

MORE INFORMATION

  • Refer to Function Parameters in the Cx51 User's Guide.
  • Refer to Application Note 129: Function Pointers in C51 for a complete discussion of all the ramifications of using function pointers with the C51 compiler.
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值