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

 
 
 
Reply to this topicStart new topic
> LPC2138/IAR, Бред какой то творится...
Velund
сообщение Jun 25 2006, 23:45
Сообщение #1


Знающий
****

Группа: Свой
Сообщений: 693
Регистрация: 19-11-04
Пользователь №: 1 177



Что то я в какую то ботву наступил с иаром. Ничего понять не могу (может оно и окажется очевидно для кого то, но меня похоже переклинило).

IAR 4.40 (с 4.31А было то же самое - попробовал обновиться именно на фоне этого глюка). LPC2138, ARM, Thumb mode - пофиг. Little endian, как водится. MT-Link первой версии, проверенный в бою.

Есть некий массив данных в памяти, повторяющиеся структуры определенного формата после некоего заголовка со своим форматом. Есть указатель, описанный как ListData * LPtr;... Первый элемент в структуре ListData - ID, тип - unsigned long. На момент выполнения вот этой вот строчки (сразу с асмом) LPtr (он в R9) равен 0x40002967.

ltemp = LPtr->Id;
0001BACC E5990000 LDR R0, [R9, #+0]
0001BAD0 E1B0A000 MOVS R10, R0

Вот кусок дампа памяти на тот же момент...

0x40002960 00 00 00 00 00 48 00 47 00 00 00 42 e6 9d 44 0c 00 04 01

Дебаггер, когда пытаешься посмотреть LPtr->Id кажет 0x00000047. Quick Watch структуру показывает как надо.

Вот только в результате выполнения той строчки в ltemp (R10) стабильно оказывается 0x00480047

Ничего понять не могу, абсолютно.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jun 26 2006, 00:13
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(Velund @ Jun 26 2006, 03:45) *
...LPtr (он в R9) равен 0x40002967

т.е. не выровнен по границе слова, и команда LDR совершенно справедливо обламывается.
Go to the top of the page
 
+Quote Post
Andy Mozzhevilov
сообщение Jun 26 2006, 03:51
Сообщение #3


Знающий
****

Группа: Свой
Сообщений: 877
Регистрация: 26-01-05
Из: Екатеринбург
Пользователь №: 2 206



Цитата(Velund @ Jun 26 2006, 05:46) *
ltemp = LPtr->Id;
0001BACC E5990000 LDR R0, [R9, #+0]
0001BAD0 E1B0A000 MOVS R10, R0

Вот кусок дампа памяти на тот же момент...

0x40002960 00 00 00 00 00 48 00 47 00 00 00 42 e6 9d 44 0c 00 04 01

Дебаггер, когда пытаешься посмотреть LPtr->Id кажет 0x00000047. Quick Watch структуру показывает как надо.

Вот только в результате выполнения той строчки в ltemp (R10) стабильно оказывается 0x00480047


Очень странно, что адрес 32 битной переменной не выровнен на 4.
В приведенном описании сложно разбираться. Сделайте минимально-достаточную структуру и функцию, в которой будет проявляться приведенный эффект и запостите сюда. Возможно, когда будете делать, все само и прояснится.


--------------------
Пасу котов...
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jun 26 2006, 07:04
Сообщение #4


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(Velund @ Jun 26 2006, 02:45) *
Есть некий массив данных в памяти, повторяющиеся структуры определенного формата после некоего заголовка со своим форматом.
Да, выравнивание виновато. Есть два пути решения:
1) При описании типа структуры сделать так:
Код
#pragma pack(push,1)
typedef struct {
   ...
}tMy_struct;
#pragma pack(pop)
это заставить обращаться к элементам структуры побайтно, т.е. правильно но медленнее.
2) Если это возможно то выровнять структуры на 4 байта.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Velund
сообщение Jun 26 2006, 07:16
Сообщение #5


Знающий
****

Группа: Свой
Сообщений: 693
Регистрация: 19-11-04
Пользователь №: 1 177



В общем понятно в чем было дело. Уже вчера в процессе засыпания до меня доперло (вспомнилась еще PDP-шная ошибка про обращение по нечетному адресу ;-) ).

Проблема была именно в выравнивании. Кусок кода, на котором я заткнулся, взят из проекта который уже не один год работает на двух разных восьмибитных платформах. И наступить в нем на такие грабли было просто удивительно поначалу - вроде куда уж более проверенное чем работающее много месяцев в сотнях изделий. ;-)

Проблема в том, что там циклически повторяющиеся 12-байтные структуры, но лежат они после хедера с длиной не кратной четырем. А в коде реализована работа с ними прямо в буфере, с использованием указателей.

ИАР ничтоже сумняшеся присваивает указателю на структуру невыровненный адрес, и без всяких предупреждений пытается вытаскивать по нему лонг... При этом симулятор и ватчи в отладчике не смотрят на асрес и показывают все корректно (хоть бы warning какой выкидывали, сволочи) ;-)

Вышел из положения заведя отдельную переменную с типом этой 12-байтной структуры, и копирую нужный блок в нее (memcpy) - все наладилось сразу.
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 25th July 2025 - 01:26
Рейтинг@Mail.ru


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