Ср июн 22, 2022 21:47:47
Ср июн 22, 2022 22:29:25
Ср июн 22, 2022 22:37:11
Чт июн 23, 2022 05:45:36
Чт июн 23, 2022 06:46:25
Чт июн 23, 2022 07:45:21
Я ошибся там не "arr", а arr_2[i]korsaj писал(а):Ну так передайте указатель. А еще лучше почитайте про указатели.
Чт июн 23, 2022 09:22:00
void big(int x) { }
void test (int *arr_2)
{
for(int i=0; i<3; i++)
{
arr_2[0]=arr_2[i];
big(arr_2[0]);
LDR R1,[R0, #+4] // R1 = arr_2[1]
STR R1,[R0, #+0] // arr_2[0] = R1
LDR R2,[R0, #+8] // R1 = arr_2[2]
STR R2,[R0, #+0] // arr_2[0] = R1
}
}
BX LR
void big(int x) { GPIOA->IDR=x; }
void test (int *arr_2)
{
for(int i=0; i<3; i++)
LDR.N R1,??DataTable2 // R1 = &GPIOA->IDR
{
arr_2[0]=arr_2[i];
big(arr_2[0]);
LDR R2,[R0, #+0] // R2 = arr_2[0]
STR R2,[R1, #+0] // GPIOA->IDR = R2
LDR R2,[R0, #+4] // R2 = arr_2[1]
STR R2,[R0, #+0] // arr_2[0] = R2
STR R2,[R1, #+0] // GPIOA->IDR = R2
LDR R2,[R0, #+8] // R2 = arr_2[2]
STR R2,[R0, #+0] // arr_2[0] = R2
STR R2,[R1, #+0] // GPIOA->IDR = R2
}
}
BX LR
void big(int x) { GPIOA->IDR=x; }
void test (int *arr_2)
{
for(int i=0; i<3; i++) big(arr_2[i]);
LDR.N R1,??DataTable2 // R1 = &GPIOA->IDR
LDR R2,[R0, #+0] // R2 = arr_2[0]
STR R2,[R1, #+0] // GPIOA->IDR = R2
LDR R2,[R0, #+4] // R2 = arr_1[1]
STR R2,[R1, #+0] // GPIOA->IDR = R2
LDR R2,[R0, #+8] // arr_1[0] = R2
STR R2,[R1, #+0] // GPIOA->IDR = R2
}
BX LR
void big(int x) { GPIOA->IDR=x; }
const int arr_1[3] = { 1,2,3 };
int main()
{
test((int *)arr_1);
LDR.N R0,??DataTable2 // R0 = &GPIOA->IDR
MOVS R1,#+1
STR R1,[R0, #+0] // GPIOA->IDR = 1;
MOVS R2,#+2
STR R2,[R0, #+0] // GPIOA->IDR = 2;
MOVS R3,#+3
STR R3,[R0, #+0] // GPIOA->IDR = 3;
}
void big(int x) { }
const int arr_1[3] = { 1,2,3 };
void test (int *arr_2)
{
for(int i=0; i<3; i++) big(arr_2[i]);
}
int main()
{
test((int *)arr_1);
for(;;);
??main_0:
B.N ??main_0
}
Сб июн 25, 2022 10:40:51
Большое спасибо, буду разбираться, пока сложно это понять)VladislavS писал(а):maksimdag0, вам надо переосмыслить как компилятор "видит" код, который вы пишете. Для него важны только volatile сущности, со всем остальным он может обходиться как хочет. Вот взять, например, компилятор IAR и ваш код с пустой функцией big(). Смотрите что получитсяКомпилятор посчитал, что это всё что делает программа. Никаких циклов и передачи параметров в функцию нет.
- Код:
void big(int x) { }
void test (int *arr_2)
{
for(int i=0; i<3; i++)
{
arr_2[0]=arr_2[i];
big(arr_2[0]);
LDR R1,[R0, #+4] // R1 = arr_2[1]
STR R1,[R0, #+0] // arr_2[0] = R1
LDR R2,[R0, #+8] // R1 = arr_2[2]
STR R2,[R0, #+0] // arr_2[0] = R1
}
}
BX LR
Теперь введём в функцию big() volatile сущность.Мы можем видеть, что добавилось полезное действие - последовательный вывод в GPIOA->IDR элементов массива.
- Код:
void big(int x) { GPIOA->IDR=x; }
void test (int *arr_2)
{
for(int i=0; i<3; i++)
LDR.N R1,??DataTable2 // R1 = &GPIOA->IDR
{
arr_2[0]=arr_2[i];
big(arr_2[0]);
LDR R2,[R0, #+0] // R2 = arr_2[0]
STR R2,[R1, #+0] // GPIOA->IDR = R2
LDR R2,[R0, #+4] // R2 = arr_2[1]
STR R2,[R0, #+0] // arr_2[0] = R2
STR R2,[R1, #+0] // GPIOA->IDR = R2
LDR R2,[R0, #+8] // R2 = arr_2[2]
STR R2,[R0, #+0] // arr_2[0] = R2
STR R2,[R1, #+0] // GPIOA->IDR = R2
}
}
BX LR
Но это ещё не всё. Немного поможем компилятору, избавим его от глупого кода.Лучше, нет лишних действий, но всё равно что-то не то. Потому что компилятор пока что не знает что мы ему в функцию передаём, это просто листинг тела функции.
- Код:
void big(int x) { GPIOA->IDR=x; }
void test (int *arr_2)
{
for(int i=0; i<3; i++) big(arr_2[i]);
LDR.N R1,??DataTable2 // R1 = &GPIOA->IDR
LDR R2,[R0, #+0] // R2 = arr_2[0]
STR R2,[R1, #+0] // GPIOA->IDR = R2
LDR R2,[R0, #+4] // R2 = arr_1[1]
STR R2,[R1, #+0] // GPIOA->IDR = R2
LDR R2,[R0, #+8] // arr_1[0] = R2
STR R2,[R1, #+0] // GPIOA->IDR = R2
}
BX LR
Попробуем эту функцию вызвать c константными данными.Ровно то что и задумано, в GPIOA->IDR последовательно записано 1,2,3 без всяких массивов и циклов вообще. Потому что GPIOA->IDR это volatile сущность и только она в этой программе важна для компилятора. Ну и для программиста, конечно, тоже, если он хочет писать привильные программы. Смотрите, что будет, если big() не будет воздействовать на volatile сущности.
- Код:
void big(int x) { GPIOA->IDR=x; }
const int arr_1[3] = { 1,2,3 };
int main()
{
test((int *)arr_1);
LDR.N R0,??DataTable2 // R0 = &GPIOA->IDR
MOVS R1,#+1
STR R1,[R0, #+0] // GPIOA->IDR = 1;
MOVS R2,#+2
STR R2,[R0, #+0] // GPIOA->IDR = 2;
MOVS R3,#+3
STR R3,[R0, #+0] // GPIOA->IDR = 3;
}Всё "почикано" под корень. Вот, это вам пища для размышлений. С опытом должно прийти понимание того что же на самом деле делает написанный вами код. Это основы языка программирования, которым почему-то нигде не учат.
- Код:
void big(int x) { }
const int arr_1[3] = { 1,2,3 };
void test (int *arr_2)
{
for(int i=0; i<3; i++) big(arr_2[i]);
}
int main()
{
test((int *)arr_1);
for(;;);
??main_0:
B.N ??main_0
}
PS: Это я ещё взял компилятор, который бережно работает с доступом по указателю. GCC бы всё это "вычистил под ноль" ещё на первом шаге.
Сб июн 25, 2022 21:34:22