Hi,
I wrote a test function as;
// Task definitions OS_TID T_Test; U64 Test_stack[13312/8]; __task void init (void); __task void Test (void) ; // Function definition uint16_t TestFunc( uint8_t a0, uint8_t a1, uint8_t a2, uint16_t a3, uint8_t a4, uint8_t a7, uint16_t a9, uint16_t a10, uint8_t* a5, uint8_t* a6, uint8_t* a8, uint8_t* a11, uint8_t* a12, uint8_t* a13) { uint16_t x; //........ return 0; } __task void init (void) { /* Initialize Tasks */ T_Test = os_tsk_create_user (Test, 1, &Test_stack, sizeof(Test_stack)); os_tsk_delete_self(); } // Call Function __task void Test (void) { uint8_t x=9,*y; uint16_t z=0x1001; y=&x; x = TestFunc(x,x,x,z,x,x,z,z,y,y,y,y,y,y); os_tsk_delete_self(); }
The last two "y" are not equal to the address of the x. I need to know passing argument limitations and the reasons of this unexpected(according to me) condition.
Need help! (asap.)
Thanks.
Thanks for your quick reply. If you want to pass that many parameters you usually just create a structure and pass in the structure's pointer to the function instead. I wrote "test" after got the error in my actual function which pass the pointers as you mentioned. i.e:
status = MyActualFunc( MyStruct1->a, MyStruct1->b, MyStruct1->c, MyStruct1->d, MyStruct1->e, MyStruct1->f, );
I saw the expected values in the stack, but not all values passed to the variables in the target function. Is it relaeted with the R0..R12 virtual register count? Because I detect the problem when I added the extra arguments. It's apparent that the problem is releated with stack, stack-pointer or something like that. I have to read the document (AAPCS) first of all.
I am waiting further suggestions. And I will share my observations.
Ally,
The reason I said it seems to be a stack alignment issue is because I ran into a similar issue when writing a routine to accept multiple paramters where this occurred.
The routine I used was something like this: void ChangeValue(UINT8 Bytes, UINT8 *p1, UINT32 *p2)
If I placed the parameters in another order such as: void ChangeValue(UINT8 *p1, UINT32 *p2, UINT8 Bytes)
The data was passed in without error. I could view the data in memory and see it was there, just not being recovered properly.
According the the document Drew linked in (good ref material BTW) there should not be any problems if the assembler follows that spec.
Set a breakpoint at the function call and step through the assembler when the data is placed into the stack, then watch the stack being populated. All data passed should be delinerated on a 4 byte boundary, according to the spec:
"B.2 If the argument is an integral Fundamental Data Type that is smaller than a word, then it is zero- or sign-extended to a full word and its size is set to 4 bytes."
Sorry, I meant view the *disassembly* window and step though the pushing and popping of the data from call and into function where it is recovered...
Also, your example of passing in your structure pointer....Why don't you just pass a pointer to MyStruct1 and operate on the elements within the function rather than passing the individual elements of the structure?
ie:
status = MyActualFunc(&MyStruct1);
then:
int MyActualFunc(struct *pMyStr) { }
Thank you Steve, I have to use a complex library written in C/C++.net. I am making some sort of reverse engineering. So I have limitted radius of action. Set a breakpoint at the function call and step through the assembler when the data is placed into the stack, then watch the stack being populated I will analize the code from assembly side as you mention.
waiting suggestions... Thanks.
Hi, In fact there was no problem. I wrote the test code attached below. When I debug the code, I saw that a12,a13,14 are not included the expected values on the local watch window. But when I assigned the argument to a temp value, the expected values called back from stack and saw the correct values on watch window assigned to the temp.
Thank you.
// Type Definition typedef struct { uint8_t a1[16]; uint8_t a2[16]; uint8_t a3[16]; uint8_t a4[16]; uint8_t a5; uint8_t a6[16]; uint8_t a7[16]; uint8_t a8[16]; uint8_t a9[16]; uint8_t a10; uint8_t a11[16]; uint8_t a12[16]; uint8_t a13[16]; uint8_t a14[16]; uint8_t a15; } TestType_t; // Test Functions // Function definitions void MyTestFunc_1( uint8_t *a1, uint8_t *a2, uint8_t *a3, uint8_t *a4, uint8_t a5, uint8_t *a6, uint8_t *a7, uint8_t *a8, uint8_t *a9, uint8_t a10, uint8_t *a11, uint8_t *a12, uint8_t *a13, uint8_t *a14, uint8_t a15) { uint8_t * x,y; x = a1; x = a2; x = a3; x = a4; y = a5; x = a6; x = a7; x = a8; x = a9; y = a10; x = a11; x = a12; x = a13; x = a14; y = a15; *x= y; } void MyTestFunc_2(TestType_t *a) { uint8_t * x,y; x = a->a1; x = a->a2; x = a->a3; x = a->a4; y = a->a5; x = a->a6; x = a->a7; x = a->a8; x = a->a9; y = a->a10; x = a->a11; x = a->a12; x = a->a13; x = a->a14; y = a->a15; *x= y; } // function calls __task void Test (void) { TestType_t *x; unsigned char i; //initial values for(i=0;i<16;i++) TestPTR->a1[i] = 0xa1; for(i=0;i<16;i++) TestPTR->a2[i] = 0xa2; for(i=0;i<16;i++) TestPTR->a3[i] = 0xa3; for(i=0;i<16;i++) TestPTR->a4[i] = 0xa4; TestPTR->a5 = 0xa5; for(i=0;i<16;i++) TestPTR->a6[i] = 0xa6; for(i=0;i<16;i++) TestPTR->a7[i] = 0xa7; for(i=0;i<16;i++) TestPTR->a8[i] = 0xa8; for(i=0;i<16;i++) TestPTR->a9[i] = 0xa9; TestPTR->a10 = 0xaa; for(i=0;i<16;i++) TestPTR->a11[i] = 0xab; for(i=0;i<16;i++) TestPTR->a12[i] = 0xac; for(i=0;i<16;i++) TestPTR->a13[i] = 0xad; for(i=0;i<16;i++) TestPTR->a14[i] = 0xae; TestPTR->a15 = 0xaf; // Test it! x=TestPTR; MyTestFunc_2(x); MyTestFunc_1(x->a1, x->a2, x->a3, x->a4, x->a5, x->a6, x->a7, x->a8, x->a9, x->a10, x->a11, x->a12, x->a13, x->a14, x->a15 ); os_tsk_delete_self(); }