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

function parameter error

1.I have defined a function as follow:
char str_cmp(const char*str1,const char*str2);
but the two parameter str1 and str2 have the same value(0x1206) after enter this function although they are different(0x0100,0x1206) in the caller.

2.another problem is the compiler locate the
explicit xdata parameter in data memory,as follow:
int xdata i;
i is located in 0x06 and I can't change the value of i with the following statment,i=10;
but if I define i as long,it is located in xdata.

  • Read generated code (directive 'code') and see optimisations to unterstand wich register contains variables and parameters.

  • I know which registers(registers bank 0) hold these parameter,but still you don't give me the answer how to solve the problem.

  • For the first problem give me the source of str_cmp().
    For the second 'problem' you must note that data at address 0x06 is register R6 in bank 0. The compiler try to put variable in register. In your specific function, it can with a int but it can't with a long.

  • char str_cmp(const char* str1,const char* str2)
    {
    int i=0;

    if(str1 == NULL || str2 == NULL) return -2;
    while(str1[i] != 0 && str2[i] != 0)
    {
    if(str1[i] == str2[i])i++;
    else break;
    }
    if(str1[i] > str2[i]) return 1;
    if(str1[i] < str2[i]) return -1;
    return 0;
    }

    int get_file_entry(const char*filename)
    {
    xdata char*name; /*for debug convenience*/
    int i;
    int j; /*for debug convenience*/

    if(filename == NULL) return -1;
    i = strlen(filename);
    if(i < 1 || i > FILE_NAME_MAX_BYTES) return -1;
    i = 0;
    while(i < MAX_FILE_COUNT)
    {
    if(file_allocating_table[i].index != -1)
    {
    name = file_allocating_table[i].name;
    j = str_cmp(name,filename);
    if(j == 0)break;
    }
    i++;
    }
    return (i < MAX_FILE_COUNT)?i:-1;
    }

    int play(const char *filename)
    {
    unsigned int index;
    _MALLOC_MEM_ *p_fd = malloc(sizeof(int));

    if(p_fd == NULL) return 0; /*no memory*/

    *p_fd = get_file_entry(filename);
    if(*p_fd == ENOENT) return ENOENT;/* file doesn't exist */

    if(sys_op_set.op_count_next_to_curr == (MAX_OPERATION_COUNT - 1)) return 0; //too many operation
    /*if there isn't operation in sys_op_set,we should use the current_op for add operation*/
    if(sys_op_set.operation[sys_op_set.current_op].operation_type != O_NON)
    sys_op_set.op_count_next_to_curr++;
    index = sys_op_set.current_op + sys_op_set.op_count_next_to_curr;
    index = index % MAX_OPERATION_COUNT;
    sys_op_set.operation[index].operation_type = O_PLAY;
    sys_op_set.operation[index].parameter = (void *)p_fd;

    return 1;
    }

    void create_operation(unsigned short key_value)
    {
    unsigned char xdata filename[12] = "1";

    switch (key_value)
    {
    case RemoteCode_1:
    creat(NULL,0);
    break;
    case RemoteCode_2:
    remove(NULL);
    break;
    case RemoteCode_3:
    start_record(1);
    break;
    case RemoteCode_4:
    stop_record();
    break;
    case RemoteCode_5:
    play(filename);
    break;
    case RemoteCode_6:
    stop_play();
    break;
    case RemoteCode_7:
    break;
    case RemoteCode_8:
    break;
    case RemoteCode_9:
    break;
    case RemoteCode_0:
    break;
    default:
    break;
    }
    }

    void remote() interrupt 0 using 3
    {
    static unsigned char key_count = 0;
    static unsigned int buf = 0;

    if(timer0_count < 4 || timer0_count > 9)
    {
    buf = 0; /* using timer1 to get logic value */
    key_count = 0;
    }
    else if(timer0_count < 7)
    {
    buf <<= 1;
    }
    else
    {
    buf <<= 1;
    buf++;
    }

    if(key_count == 11)
    {
    create_operation(buf & 0x00ff);
    IE&=0xfe;//Fe;
    timer0_count=0;
    key_count=0;
    return;
    }
    else
    {
    TR0 = 0;
    TH0 = 0xf7;
    TL0 = 0x36;
    TR0 = 1;
    timer0_count = 0;
    }
    key_count++;
    }

    void timer0(void) interrupt 1 using 2
    {
    TR0 = 0; /*stop T0 while it is reloaded*/
    TH0 = 0xf7; /*give a 27MHz clock*/
    TL0 = 0x36; /*set T0 to overflow in 1ms*/
    TR0 = 1; /*restart T0*/
    if((IE&0x01)==0)
    {
    if(timer0_count>285)
    {
    TR0 = 0;
    timer0_count = 0;
    IE |= 0x01;
    }
    }
    timer0_count++;
    }

    str_cmp is called as follow:
    remote()-->create_operation()-->play()-->get_file_entry()-->str_cmp().

    Does the internal memory can hold so many parameters?

    Is the reason that I don't use the control directive such as NOAREGS or AREGS? But I don't know how to use them.

    Note:the project is compiled in large mode.

  • 2.another problem is the compiler locate the
    explicit xdata parameter in data memory,as follow:
    int xdata i;
    i is located in 0x06 and I can't change the value of i with the following statment,i=10;
    but if I define i as long,it is located in xdata.


    By default, the compiler passes up to 3 function arguments in registers. This is much faster than passing the arguments in fixed memory locations. If you don't want the compiler to use registers for your parameters take a look at the NOREGPARMS dirctive. This will slow down your program and increase the size of the code nicely.

    Jon

  • Please use the < pre > and < /pre > HTML tags when posting souce code.

    Regarding your first question. Have you taken into account the fact that these are generic pointers? Just a thought. How are you getting at the value of the variables, the C51 optimisations can leave the debugger confused. To be sure of what is going on, you may need to step through each disasembly instruction.

    Your question says:
    2.another problem is the compiler locate the
    explicit xdata parameter in data memory,as follow:
    int xdata i;
    i is located in 0x06 and I can't change the value of i with the following statment,i=10;
    but if I define i as long,it is located in xdata.


    However, in your source code you have:

    char str_cmp(const char* str1,const char* str2)
    {
        int i=0;
        ....
    }
    
    When compiling with the large memory model, C51 will put automatic variables into registers if it can and will otherwise place them in the memory specified by the memory model. This is what has happened in this case: address 0x06 is the address of register R6 in bank 0. There are enough free registers for an int, but too few for a long. If you explicitly place the variable (using the syntax indicated in your question) you should find that the variable turns up in xdata.

  • It's ok after I used the directive NOREGPARMS.
    Thanks to everyone.