реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Косяк в компиляторе KEIL по части автоинкремента?
KnightIgor
сообщение Dec 19 2012, 12:44
Сообщение #1


Знающий
****

Группа: Участник
Сообщений: 643
Регистрация: 29-05-09
Из: Германия
Пользователь №: 49 725



Привет, коллеги.

Столкнулся с "интересным" поведением программы под KEIL 4.23, процессор EFM32G210F128:
Код
void func(void *p)
{
   long *ptr = p;
   ...
   *ptr++ = variable;
   ...
}

приводит к исключению. В ассемблере это инструкция STM R5!, {R0}.
Код
void func(void *p)
{
   long *ptr = p;
   ...
   *ptr = variable;
    ptr++;
   ...
}

работает нормально. Там генерируется:
Код
  STR R0, [R5, #0x00]
  ADDS R5,R5,#4

В описании инструкции STM я не нашел упоминания, что регистр-указатель приемника должен быть выровнен на слово, а похоже именно это требуется. У меня же через void *p передается указатель на некий буфер обмена, который может содержать различные данные, а сам буфер в итоге где-то в стеке как локальная переменная внутри функции, которая и вызывает мою. Очевидно, что локальные переменные там не выровнены.

Что скажете? Мой недосмотр или грабли, подложенные KEIL?
Go to the top of the page
 
+Quote Post
esaulenka
сообщение Dec 19 2012, 13:07
Сообщение #2


Профессионал
*****

Группа: Свой
Сообщений: 1 032
Регистрация: 13-03-08
Из: Маськва
Пользователь №: 35 877



поиск по arm.com "cortex-m3 unaligned access"

Цитата
The Cortex-M3 processor supports unaligned access only for the following instructions:
LDR, LDRT
LDRH, LDRHT
LDRSH, LDRSHT
STR, STRT
STRH, STRHT.
All other load and store instructions generate a UsageFault exception if they perform an unaligned access, and therefore their accesses must be address aligned.


Так что контроллер работает согласно спецификации :-)

К кейлу тоже никаких претензий - он же не знает, что этот указатель не выравнивается.


PS. Вот так должно работать.


--------------------
Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам ©
Go to the top of the page
 
+Quote Post
KnightIgor
сообщение Dec 19 2012, 14:22
Сообщение #3


Знающий
****

Группа: Участник
Сообщений: 643
Регистрация: 29-05-09
Из: Германия
Пользователь №: 49 725



Цитата(esaulenka @ Dec 19 2012, 14:07) *
PS. Вот так должно работать.

Понял, спасибо.

Дополню.
Цитата
К кейлу тоже никаких претензий - он же не знает, что этот указатель не выравнивается.

Ну... здесь можно поспорить. С точки зрения C оба кода вполне равноценны и должны быть переносимы. А получается, что кусок кода c *p++ шустрил успешно на каком-нибудь 8-ми битнике, а тут на Cortex вдруг раз, и исключение! И только потому, что платформа себя так ведет, что к C никакого отношения не имеет. Некрасиво.

Сообщение отредактировал KnightIgor - Dec 19 2012, 15:39
Go to the top of the page
 
+Quote Post
ar__systems
сообщение Dec 19 2012, 16:12
Сообщение #4


self made
****

Группа: Свой
Сообщений: 855
Регистрация: 7-03-09
Из: Toronto, Canada
Пользователь №: 45 795



Цитата(KnightIgor @ Dec 19 2012, 09:22) *
Понял, спасибо.

Дополню.

Ну... здесь можно поспорить. С точки зрения C оба кода вполне равноценны и должны быть переносимы. А получается, что кусок кода c *p++ шустрил успешно на каком-нибудь 8-ми битнике, а тут на Cortex вдруг раз, и исключение! И только потому, что платформа себя так ведет, что к C никакого отношения не имеет. Некрасиво.
Тут дело не в *p++, а в том, чтовы указатель конвертируете из войд в лонг. На 8ми битнике понятное дело будет работать, на то он и 8ми битник чтобы про выравнивание не знать. Вы не получили warning при компиляции, что assignment increases alignment requirements? Компилятор ведет себя правильно. Вы же в курсе, что невыровненый доступ занимает больше времени?
Go to the top of the page
 
+Quote Post
KnightIgor
сообщение Dec 19 2012, 16:25
Сообщение #5


Знающий
****

Группа: Участник
Сообщений: 643
Регистрация: 29-05-09
Из: Германия
Пользователь №: 49 725



Цитата(ar__systems @ Dec 19 2012, 17:12) *
Вы не получили warning при компиляции, что assignment increases alignment requirements?

Нет.
Цитата
Вы же в курсе, что невыровненый доступ занимает больше времени?

Да. Но здесь я бы ожидал, что компилятор в угоду совместимости будет исходить из НЕвыровненных данных. А программист, который хочет быстро, может указать потом, какие данные выровнены, и если ошибется - пусть пеняет на себя же. То есть, не __packed нужно, что для меня выглядит как work around, а противоположный описатель типа __aligned. Тогда совместимость на уровне исходника будет, а оптимизацией под платформу можно будет заняться, если припечёт.

Сообщение отредактировал KnightIgor - Dec 19 2012, 17:23
Go to the top of the page
 
+Quote Post
scifi
сообщение Dec 19 2012, 17:41
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(KnightIgor @ Dec 19 2012, 20:25) *
Но здесь я бы ожидал, что компилятор в угоду совместимости будет исходить из НЕвыровненных данных. А программист, который хочет быстро, может указать потом, какие данные выровнены, и если ошибется - пусть пеняет на себя же.

В стандарте языка закреплено обратное: по умолчанию предполагается, что все объекты выровнены должным образом.
Что касается конкретно этого случая, то тут надо в деталях разбирать происхождение указателя на void. Тогда будет видно, где именно возникает невыровненный объект. Ну а работать с ним можно, используя packed (непереносимая фича компилятора), или делать перепаковку руками (переносимо).
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 23rd July 2025 - 07:29
Рейтинг@Mail.ru


Страница сгенерированна за 0.01378 секунд с 7
ELECTRONIX ©2004-2016