Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: LPC2138/IAR
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Velund
Что то я в какую то ботву наступил с иаром. Ничего понять не могу (может оно и окажется очевидно для кого то, но меня похоже переклинило).

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

Ничего понять не могу, абсолютно.
aaarrr
Цитата(Velund @ Jun 26 2006, 03:45) *
...LPtr (он в R9) равен 0x40002967

т.е. не выровнен по границе слова, и команда LDR совершенно справедливо обламывается.
Andy Mozzhevilov
Цитата(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.
В приведенном описании сложно разбираться. Сделайте минимально-достаточную структуру и функцию, в которой будет проявляться приведенный эффект и запостите сюда. Возможно, когда будете делать, все само и прояснится.
Сергей Борщ
Цитата(Velund @ Jun 26 2006, 02:45) *
Есть некий массив данных в памяти, повторяющиеся структуры определенного формата после некоего заголовка со своим форматом.
Да, выравнивание виновато. Есть два пути решения:
1) При описании типа структуры сделать так:
Код
#pragma pack(push,1)
typedef struct {
   ...
}tMy_struct;
#pragma pack(pop)
это заставить обращаться к элементам структуры побайтно, т.е. правильно но медленнее.
2) Если это возможно то выровнять структуры на 4 байта.
Velund
В общем понятно в чем было дело. Уже вчера в процессе засыпания до меня доперло (вспомнилась еще PDP-шная ошибка про обращение по нечетному адресу ;-) ).

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

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

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

Вышел из положения заведя отдельную переменную с типом этой 12-байтной структуры, и копирую нужный блок в нее (memcpy) - все наладилось сразу.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.