VDSP函數調用時的參數傳遞__函數
來源:互聯網
上載者:User
本文開發環境: VDSP 5.0 1 沒有參數時的函數調用 void sub(void) { } void func(void) { sub(); // CALL sub; } 這是最簡單的一個函數調用了,直接使用CALL,沒有任何其它的處理。 2 <=3個參數時的處理 void sub(int a, int b, int c) { // LINK 0x0; // [FP + 0x10] = R2; // [FP + 0xc] = R1; // [FP + 0x8] = R0; // UNLINK; } void func(void) { // LINK 0xc; sub(1, 2, 3); // R2 = 3; // R1 = 2; // R0 = 1; // CALL sub; } 從以上代碼可以看出,當參數個數小於等於3個的時候,VDSP將使用R0,R1,R2進行參數的傳遞。從上面的代碼還可以看出,函數參數的堆棧空間是由調用函數(func)來分配的,這也是func函數中使用LINK 0xc保留12個位元組堆棧空間的原因。需要注意的是即使sub函數沒有參數,func也會保留12個位元組的堆棧空間。之所以是從[FP + 0x8]開始儲存參數,是因為LINK指令會將RETS和FP兩個寄存器入棧,從而使SP向下增長了8個位元組。 3 >3個參數時的處理 void sub(int a, int b, int c, int d, int e) { // R3 = [FP + 0x14]; // R7 = [FP + 0x18]; // [FP + 0x18] = R7; // [FP + 0x14] = R3; // [FP + 0x10] = R2; // [FP + 0xc] = R1; // [FP + 0x8] = R0; } void func(void) { sub(1, 2, 3, 4, 5); // P1 = 5; // [SP + 0x10] = P1; // P1 = 4; // [SP + 0xc] = P1; // R2 = 3; // R1 = 2; // R0 = 1; // CALL sub; } 從以上代碼可以看出,VDSP將參數從右往左依次入棧,再調用子函數,子函數則直接使用堆棧中的資料。 4 參數個數不匹配時的處理 void func(void) { sub(1, 2, 3, 4, 5); // P1 = 5; // [SP + 0x10] = P1; // P1 = 4; // [SP + 0xc] = P1; // R2 = 3; // R1 = 2; // R0 = 1; // CALL sub; } void sub(int a, int b) { // [FP + 0xc] = R1; // [FP + 0x8] = R0; } 在C編譯器中,形參與實參的個數是可以不匹配的,僅僅給出一個警告。從上述代碼可以看出,調用函數和被調用的函數都是根據自己看到的參數來進行處理的,這樣當實參的個數少於形參的個數時,幾乎可以肯定會出錯。因為子函數無法取到正確的參數值。 5 關於傳回值 int sub(int a, int b) { return a - b; // R0 = R0 – R1(NS); // UNLINK; // RTS; } void func(void) { int a; a = sub(5, 3); // R1 = 3; // R0 = 5; // CALL sub; // [FP + 0x8] = R0; } 從上述彙編代碼很容易可以看出,VDSP使用R0儲存傳回值。