Например TDA7294

Форум РадиоКот • Просмотр темы - Вопрос по массиву
Форум РадиоКот
Здесь можно немножко помяукать :)

Текущее время: Вт дек 30, 2025 06:37:21

Часовой пояс: UTC + 3 часа


ПРЯМО СЕЙЧАС:



Начать новую тему Ответить на тему  [ Сообщений: 9 ] 
Автор Сообщение
Не в сети
 Заголовок сообщения: Вопрос по массиву
СообщениеДобавлено: Ср июн 22, 2022 21:47:47 
Прорезались зубы

Зарегистрирован: Чт апр 08, 2021 09:46:48
Сообщений: 225
Рейтинг сообщения: 0
Все добрый вечер!
Я столкнулся с таким случаем: передаю массив в функцию test, через указатель (см. фото 1). В теле этой функции я передаю массив другой функции - big, но передаю по одному элементу таким образом - каждый элемент массива преравниваю к первому элементу и передаю его в функцию big, НО это не работает, почему? Почему нельзя записать в первый элемент массива его любой другой элемент? (см. фото 2)
Я отслеживал под отладкой это процесс, и выявил что никакое значение не записывается в первый элемент массива, и даже больше значение arr[i] не изменялось вообще, хотя переменная "i" изменялась. подскажите пожалуйста, что я не знаю, почему так происходит?


Вложения:
Screenshot_2.png [3.07 KiB]
Скачиваний: 112
Screenshot_1.png [1.44 KiB]
Скачиваний: 91
Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Вопрос по массиву
СообщениеДобавлено: Ср июн 22, 2022 22:29:25 
Потрогал лапой паяльник
Аватар пользователя

Карма: 2
Рейтинг сообщений: 13
Зарегистрирован: Чт июн 23, 2011 07:55:51
Сообщений: 330
Рейтинг сообщения: 0
Ну так передайте указатель. А еще лучше почитайте про указатели.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Вопрос по массиву
СообщениеДобавлено: Ср июн 22, 2022 22:37:11 
Собутыльник Кота
Аватар пользователя

Карма: 18
Рейтинг сообщений: 433
Зарегистрирован: Вт май 01, 2018 19:44:47
Сообщений: 2557
Рейтинг сообщения: 0
Как объявлен arr предлагается угадать?


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Вопрос по массиву
СообщениеДобавлено: Чт июн 23, 2022 05:45:36 
Встал на лапы

Карма: -10
Рейтинг сообщений: 17
Зарегистрирован: Сб июн 04, 2022 05:21:07
Сообщений: 148
Рейтинг сообщения: 0
Там у вас всё чето сильно позапутано всё, неясна конечная цель и что для чего делается. Если нулевому элементу входного массива присваивается значение из неизвестно откуда взявшегося массива, а потом этот элемент передается в другую функцию, то можно всю эту цепочку сократить, убрав лишние действия:


Вернуться наверх
 
Эиком - электронные компоненты и радиодетали
Не в сети
 Заголовок сообщения: Re: Вопрос по массиву
СообщениеДобавлено: Чт июн 23, 2022 06:46:25 
Мучитель микросхем

Карма: 4
Рейтинг сообщений: 80
Зарегистрирован: Вс ноя 01, 2015 09:15:16
Сообщений: 445
Откуда: 69.Ржев
Рейтинг сообщения: 0
отключите оптимизацию
компилятор, скорее всего, просто вас не понял


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Вопрос по массиву
СообщениеДобавлено: Чт июн 23, 2022 07:45:21 
Прорезались зубы

Зарегистрирован: Чт апр 08, 2021 09:46:48
Сообщений: 225
Рейтинг сообщения: 0
korsaj писал(а):
Ну так передайте указатель. А еще лучше почитайте про указатели.
Я ошибся там не "arr", а arr_2[i]


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Вопрос по массиву
СообщениеДобавлено: Чт июн 23, 2022 09:22:00 
Собутыльник Кота
Аватар пользователя

Карма: 18
Рейтинг сообщений: 433
Зарегистрирован: Вт май 01, 2018 19:44:47
Сообщений: 2557
Рейтинг сообщения: 2
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 сущность.
Код:
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
Мы можем видеть, что добавилось полезное действие - последовательный вывод в GPIOA->IDR элементов массива.

Но это ещё не всё. Немного поможем компилятору, избавим его от глупого кода.
Код:
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 константными данными.
Код:
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;
}
Ровно то что и задумано, в GPIOA->IDR последовательно записано 1,2,3 без всяких массивов и циклов вообще. Потому что GPIOA->IDR это volatile сущность и только она в этой программе важна для компилятора. Ну и для программиста, конечно, тоже, если он хочет писать привильные программы. Смотрите, что будет, если big() не будет воздействовать на volatile сущности.
Код:
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 бы всё это "вычистил под ноль" ещё на первом шаге.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Вопрос по массиву
СообщениеДобавлено: Сб июн 25, 2022 10:40:51 
Прорезались зубы

Зарегистрирован: Чт апр 08, 2021 09:46:48
Сообщений: 225
Рейтинг сообщения: 0
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 сущность.
Код:
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
Мы можем видеть, что добавилось полезное действие - последовательный вывод в GPIOA->IDR элементов массива.

Но это ещё не всё. Немного поможем компилятору, избавим его от глупого кода.
Код:
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 константными данными.
Код:
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;
}
Ровно то что и задумано, в GPIOA->IDR последовательно записано 1,2,3 без всяких массивов и циклов вообще. Потому что GPIOA->IDR это volatile сущность и только она в этой программе важна для компилятора. Ну и для программиста, конечно, тоже, если он хочет писать привильные программы. Смотрите, что будет, если big() не будет воздействовать на volatile сущности.
Код:
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 бы всё это "вычистил под ноль" ещё на первом шаге.
Большое спасибо, буду разбираться, пока сложно это понять)


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Вопрос по массиву
СообщениеДобавлено: Сб июн 25, 2022 21:34:22 
Мучитель микросхем

Карма: 4
Рейтинг сообщений: 80
Зарегистрирован: Вс ноя 01, 2015 09:15:16
Сообщений: 445
Откуда: 69.Ржев
Рейтинг сообщения: 0
что сложно?
речь, почему можете не увидеть Ваш код на выходе компиляции.
примерьте ситуацию на себя - Вы будете перетаскивать кирпичи с места на место, если в этом нет ну совершенно никакой потребности?
если цепочка команд не приводит каким-либо практическим результатам - эта цепочка компилятором может быть "забыта". применительно к Вашему массиву - если содержание массива Вы в дальнейшем никак не используете и компилятор это "просматривает" - ну и зачем ему что-то конфигурить для сущности у которой не будет никакого применения: ни применена в дальнейших расчетах, ни выведена "наружу", ни передана в периферию ...
Хотите увидеть абстрактно как может быть скомпилирован Ваш код, отключите оптимизацию - будет оттранслирован "как есть", без учета "а что собственно нужно" и "как это оптимальнее сделать".

в двух стилях вам рассказали :)
Владислав профессионально и наглядно.
ну и вот, типа на пальцах


Вернуться наверх
 
Показать сообщения за:  Сортировать по:  Вернуться наверх
Начать новую тему Ответить на тему  [ Сообщений: 9 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на форуме

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 24


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB
Extended by Karma MOD © 2007—2012 m157y
Extended by Topic Tags MOD © 2012 m157y