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

 
 
3 страниц V  < 1 2 3 >  
Reply to this topicStart new topic
> Q: знатокам arm-вского ассемблера
defunct
сообщение Aug 7 2006, 10:19
Сообщение #16


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(zltigo @ Aug 7 2006, 13:00) *
Никаких передач через void * или преобразования типов нет, все явно указано - мог, как минимум, предупредить.

Видимо и предупредил. Тема интересная. Вечером попробую повторить описанный глюк.
abcdefg какую версию keil'a Вы использовали?
Go to the top of the page
 
+Quote Post
Harbour
сообщение Aug 7 2006, 11:14
Сообщение #17


Местами Гуру
*****

Группа: Validating
Сообщений: 1 103
Регистрация: 5-12-04
Пользователь №: 1 323



Цитата(zltigo @ Aug 7 2006, 13:00) *
Цитата(Harbour @ Aug 7 2006, 12:36) *

что-то видать намучено в linker script с align опцией

Linker тут практически ни причем, поскольку оперирует линковкой сегментов.


Задав неверную опцию выравнивания для data секции можно тоже получить данный эффект - правда нужно умудриться написать при этом работоспособный код.

Цитата
Ну а компилятор - в данном контексте имел возможность отругаться и не выдавать из пакованной структуры смещенный адрес dword. Никаких передач через void * или преобразования типов нет, все явно указано - мог, как минимум, предупредить.


Где-то стоит опция по умолчанию паковать все структуры. Код небрежный - отсюда и результат. Автору нужно прочитать "веревку" Аллена, однозначно.
Go to the top of the page
 
+Quote Post
Harbour
сообщение Aug 7 2006, 11:40
Сообщение #18


Местами Гуру
*****

Группа: Validating
Сообщений: 1 103
Регистрация: 5-12-04
Пользователь №: 1 323



Проверил на arm-elf-gcc 4.1.1 - в любом случае (packed/non-packed struct) генерит корректный с точки зрения архитектуры код - в случае non-packed он вставляет gap, а в случае packed располагает структуру так что field3 находится по выровненному адресу. Вот те и gcc, который все ругают wink.gif
Go to the top of the page
 
+Quote Post
zltigo
сообщение Aug 7 2006, 11:55
Сообщение #19


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(Harbour @ Aug 7 2006, 14:40) *
а в случае packed располагает структуру так что field3 находится по выровненному адресу.

Ну это достаточно похоже на случайность, к истине можно приблизится если попробовать запихнуть два dword разделив их byte (естественно packed) и повторив фокус с обеими.


P.S.
GCC я не ругал :-)
z.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
defunct
сообщение Aug 7 2006, 13:33
Сообщение #20


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата
Код небрежный - отсюда и результат. Автору нужно прочитать "веревку" Аллена, однозначно.

Не.. этот совет здесь не годится.
Причинно-следственная связь другая. ;>
Сказать:
- "всегда грамотно оформляйте структуры, потому что иначе, используя Keil, можете получить data abort"
это неравносильно тому что пишут в книгах:
- "оформляйте структуры грамотно для повышения пр-ти и сокращения объема, за счет естественного выравнивания".

Понятно, что в идеале эту структуру нужно полностью перевернуть, однако (пока что неподтвержденный) факт неверного выравнивания компилятором остается. И спасибо автору ветки за то, что он его словил.
Go to the top of the page
 
+Quote Post
abcdefg
сообщение Aug 7 2006, 13:46
Сообщение #21


Местный
***

Группа: Свой
Сообщений: 201
Регистрация: 23-01-06
Из: Msk
Пользователь №: 13 490



Цитата(defunct @ Aug 7 2006, 14:19) *
Цитата(zltigo @ Aug 7 2006, 13:00) *

Никаких передач через void * или преобразования типов нет, все явно указано - мог, как минимум, предупредить.

Видимо и предупредил. Тема интересная. Вечером попробую повторить описанный глюк.
abcdefg какую версию keil'a Вы использовали?


Keil соответсвенно последний (mdk302a, компилятор 2.54a).
Void'ский указатель, упомянутый в самом начале, оказался не причем (т.к. думал, что проблема из-за преобразования в void* )
Go to the top of the page
 
+Quote Post
defunct
сообщение Aug 7 2006, 21:20
Сообщение #22


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Для тестов использовал приведенный выше пример Сишного кода.

Цитата
U32 *ptr1= &(test_str.field3);

test_str.field1 = 0x11; // ok
test_str.field2 = 0x2233; // ok
test_str.field3 = 0x44556677; // ok

*ptr1 = 0x00000000; // bug, тут происходит запись в "выравненный адрес"


для неупакованной структуры:

Код
struct {
U8 field1;
U16 field2;
U32 field3;
} test_str;


Был сгенерирован следующий код:
Код
    28: U32 *ptr1= &(test_str.field3);
    29:  
0x00000176  4910      LDR       R1,[PC,#0x0040]
0x00000178  4A10      LDR       R2,[PC,#0x0040]
    30: test_str.field1 = 0x11; // ok
0x0000017A  2011      MOV       R0,#0x11
0x0000017C  7008      STRB      R0,[R1,#0x00]
    31: test_str.field2 = 0x2233; // ok
0x0000017E  4810      LDR       R0,[PC,#0x0040]
0x00000180  8048      STRH      R0,[R1,#0x02]
    32: test_str.field3 = 0x44556677; // ok
    33:  
0x00000182  4810      LDR       R0,[PC,#0x0040]
0x00000184  6048      STR       R0,[R1,#0x04]
    34: *ptr1 = 0x00000000; // bug, тут происходит запись в "выравненный адрес"
0x00000186  2100      MOV       R1,#0x00
0x00000188  1C10      ADD       R0,R2,#0
0x0000018A  6001      STR       R1,[R0,#0x00]


Как видно из листинга Keil дополнил стуктуру padding байтом по адресу test_str+1. И код получился вполне грамотным.

А вот для упакованной структуры....

Код
struct {
U8 field1;
U16 field2;
U32 field3;
} __packed test_str;

0x00000176  4815      LDR       R0,[PC,#0x0054]
0x00000178  4B15      LDR       R3,[PC,#0x0054]
    30: test_str.field1 = 0x11; // ok
0x0000017A  2111      MOV       R1,#0x11
0x0000017C  7001      STRB      R1,[R0,#0x00]
    31: test_str.field2 = 0x2233; // ok
0x0000017E  4915      LDR       R1,[PC,#0x0054]
0x00000180  4815      LDR       R0,[PC,#0x0054]
0x00000182  7001      STRB      R1,[R0,#0x00]
0x00000184  0A09      LSR       R1,R1,#8
0x00000186  7041      STRB      R1,[R0,#0x01]
    32: test_str.field3 = 0x44556677; // ok
    33:  
0x00000188  4914      LDR       R1,[PC,#0x0050]
0x0000018A  4811      LDR       R0,[PC,#0x0044]
0x0000018C  7001      STRB      R1,[R0,#0x00]
0x0000018E  0A09      LSR       R1,R1,#8
0x00000190  7041      STRB      R1,[R0,#0x01]
0x00000192  0A09      LSR       R1,R1,#8
0x00000194  7081      STRB      R1,[R0,#0x02]
0x00000196  0A09      LSR       R1,R1,#8
0x00000198  70C1      STRB      R1,[R0,#0x03]
    34: *ptr1 = 0x00000000; // bug, тут происходит запись в "выравненный адрес"
0x0000019A  2100      MOV       R1,#0x00
0x0000019C  1C18      ADD       R0,R3,#0
0x0000019E  6001      STR       R1,[R0,#0x00] // <-- Тут R0 = 493


Как следствие затираются первые два поля структуры (field1, field2) и младший байт третьего поля, хотя результатом последней строки Сишного кода должно было быть обнуление field3. При чтении значения по указателю *ptr был сделан хитрый трюк:
Код
    35: X = *ptr1;
0x000001A0  1C18      ADD       R0,R3,#0
0x000001A2  6800      LDR       R0,[R0,#0x00]
0x000001A4  6088      STR       R0,[R1,#0x08]


Т.о. причитался сохраненный ранее 0.. Вот так дела..
Никакого Warining'a либо ошибки при компиляции выдано не было.

Так что проблема с компилятором действительно имеет место быть! Проверял на keil 3.23, CA 2.32, 2.40, 2.41, 2.42...
Автору ветки большое спасибо еще раз.

Сообщение отредактировал defunct - Aug 7 2006, 21:22
Go to the top of the page
 
+Quote Post
goodwin
сообщение Aug 7 2006, 21:39
Сообщение #23


Местный
***

Группа: Свой
Сообщений: 481
Регистрация: 1-08-05
Пользователь №: 7 267



Вот и я о том. Лучше перебдеть, чем недобдеть - расставить все ручками в структуре и добавить байтик при необходимости...
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Aug 8 2006, 01:20
Сообщение #24


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Фактически была некорректной эта команда:
Код
U32 *ptr1= &(test_str.field3);
У меня ИАР на неё заругался (выдал Warning). А когда структура в стеке, то вообще отказался компилить и выдал Error.


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
defunct
сообщение Aug 9 2006, 12:38
Сообщение #25


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Отправил bug report в Keil, сказали пофиксят..
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Aug 10 2006, 11:53
Сообщение #26


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Нашёл у себя в ИАР то ли баг, то ли я тупой?
Напишу в этой же ветке, так как проблема почти один в один.
Такой вот код меня удивляет:
Код
char *ptr = getAddr();
float val = *(float *)ptr;
Я почему-то надеялся, что преобразуя байтовый указатель в любой другой он наследует его байтовое выравнивание (фактически отсутствие выравнивания) и компилер должен корректно считывать любые типы. Но что-то случилось...
Короче, кто из нас двоих тупой?


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Aug 10 2006, 12:18
Сообщение #27


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Или может я ошибаюсь? Может выравнивание прикрепляется только к создаваемым новым типам, например к структурам и юнионам?


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Aug 10 2006, 12:33
Сообщение #28


Гуру
******

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



Цитата(GetSmart @ Aug 10 2006, 15:18) *
Или может я ошибаюсь? Может выравнивание прикрепляется только к создаваемым новым типам, например к структурам и юнионам?
Точнее к полям структуры. Т.е. если через указатель на эту упакованную структуру будешь обращаться к ее полям, то обращение будет побайтовым. А корректность указателей на поля упакованной структуры никто не обещал. Та кчто ошибаешься.


--------------------
На любой вопрос даю любой ответ
"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
GetSmart
сообщение Aug 10 2006, 13:30
Сообщение #29


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Ну допустим. Тогда как проще (и желательно красивее) всего прочитать число допустим float с байтового адреса?


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
ek74
сообщение Aug 10 2006, 14:32
Сообщение #30


Частый гость
**

Группа: Свой
Сообщений: 81
Регистрация: 4-08-05
Из: г. Саратов
Пользователь №: 7 351



Цитата(GetSmart @ Aug 10 2006, 17:30) *
Ну допустим. Тогда как проще (и желательно красивее) всего прочитать число допустим float с байтового адреса?


Как выриант:
Код
float val;
char *ptr = getAddr();
memcpy(&val, ptr, sizeof(val));


Не сказать, что проще и красивее, но это универсальная конструкция, которая будет работать независимо от архитектуры контроллера и особенностей компилятора.
Go to the top of the page
 
+Quote Post

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

 


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


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