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

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


Местный
***

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



есть команда STR R1, [R0, #0x0]
при R1 = 0x00000000, R0 = 0x400002B5
пишет нули по адресу 0x400002B4 !!!

Есть ли выравнивание по адресу записи?! Если это так, то надо аккуратно работать в keil'e с void-скими указателями sad.gif
Go to the top of the page
 
+Quote Post
DASM
сообщение Aug 5 2006, 17:33
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493



Цитата(abcdefg @ Aug 5 2006, 20:54) *
есть команда STR R1, [R0, #0x0]
при R1 = 0x00000000, R0 = 0x400002B5
пишет нули по адресу 0x400002B4 !!!

Есть ли выравнивание по адресу записи?! Если это так, то надо аккуратно работать в keil'e с void-скими указателями sad.gif

Data can be 8-bit bytes, 16-bit halfwords, or 32 bit doubles. Words MUST BE ALLIGNED to 4-byte boundaries, halfwords must be aligned to 2-byte boundaries
И Keil тут не причем - архитектура однако

Сообщение отредактировал DASM - Aug 5 2006, 17:34
Go to the top of the page
 
+Quote Post
zltigo
сообщение Aug 5 2006, 17:48
Сообщение #3


Гуру
******

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



Цитата(DASM @ Aug 5 2006, 20:33) *
И Keil тут не причем - архитектура однако

С архитектурными ограниченими дело ясное. Но если Keil вдруг сваял такой ассеблерный код из вполне внятного "C", то он "причем" :-(.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
DASM
сообщение Aug 5 2006, 18:18
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493



Цитата(zltigo @ Aug 5 2006, 21:48) *
Цитата(DASM @ Aug 5 2006, 20:33) *

И Keil тут не причем - архитектура однако

С архитектурными ограниченими дело ясное. Но если Keil вдруг сваял такой ассеблерный код из вполне внятного "C", то он "причем" :-(.

гм.. ну так если Keil - у предложили указатель на void - то как бы чего он выравнивать то будет.... то есть смотря как этот указатель инициализировали.. а томже товарищ присвоил указателю адресу байтового массива, а переда его в функцию где int * хочетца ... голова что-то плохо с утра варит, но что-то в этом роде

Сообщение отредактировал DASM - Aug 5 2006, 18:19
Go to the top of the page
 
+Quote Post
Rst7
сообщение Aug 6 2006, 10:58
Сообщение #5


Йа моск ;)
******

Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610



Цитата(abcdefg @ Aug 5 2006, 19:54) *
есть команда STR R1, [R0, #0x0]
при R1 = 0x00000000, R0 = 0x400002B5
пишет нули по адресу 0x400002B4 !!!

Есть ли выравнивание по адресу записи?! Если это так, то надо аккуратно работать в keil'e с void-скими указателями sad.gif


А что вас так испугало? Читаем описание инструкции STR и видим там (документ ARM DDI 0100E стр. A4-89):
Цитата
Non word-aligned addresses
STR instructions ignore the least significant two bits of address. So if these bits are not
0b00, the effects of STR are not precisely opposite to those of LDR.


Так что для STR два младших бита игнорируются. А для LDR такое не прокатит, дата аборт сразу...


--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
Go to the top of the page
 
+Quote Post
zltigo
сообщение Aug 6 2006, 11:26
Сообщение #6


Гуру
******

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



Цитата(Rst7 @ Aug 6 2006, 13:58) *
А что вас так испугало?

Очевидно получение неожиданного и без всяких предупреждений результата на ARM платформе (в отличие , например, от x86 платформы на которой обращение по невыровненному адресу хоть и медленнее, но корректно выполнится). И необходимость держать такой "нюанс" в голове программиста.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Rst7
сообщение Aug 6 2006, 11:53
Сообщение #7


Йа моск ;)
******

Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610



Цитата(zltigo @ Aug 6 2006, 14:26) *
Цитата(Rst7 @ Aug 6 2006, 13:58) *

А что вас так испугало?

Очевидно получение неожиданного и без всяких предупреждений результата на ARM платформе (в отличие , например, от x86 платформы на которой обращение по невыровненному адресу хоть и медленнее, но корректно выполнится). И необходимость держать такой "нюанс" в голове программиста.


Ну как сказать - неожиданный, на 68000 - аналогично, правда там exception и при записи происходит (а вот начиная с 030 - уже работает невыровненный доступ), PPC - тоже отказывается работать с невыровненными данными, да пожалуй все RISC такие; из классики - PDP11 - тоже самое, IBM360/370 - тоже, вот VAX - не помню. Так что x86 реально в меньшенстве...


--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
Go to the top of the page
 
+Quote Post
zltigo
сообщение Aug 6 2006, 12:11
Сообщение #8


Гуру
******

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



Цитата(Rst7 @ Aug 6 2006, 14:53) *
Так что x86 реально в меньшенстве...

Но не по привычности/распространенности. Да ведет себя 'правильнее' в данной ситуации.
Давить? :-)))


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Rst7
сообщение Aug 6 2006, 12:24
Сообщение #9


Йа моск ;)
******

Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610



Цитата
Давить? :-)))

Что??? Куда???

Да и это вам привычней, а нам нет wink.gif

Сообщение отредактировал Rst7 - Aug 6 2006, 12:25


--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
Go to the top of the page
 
+Quote Post
abcdefg
сообщение Aug 6 2006, 18:00
Сообщение #10


Местный
***

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



Цитата(DASM @ Aug 5 2006, 22:18) *
гм.. ну так если Keil - у предложили указатель на void - то как бы чего он выравнивать то будет.... то есть смотря как этот указатель инициализировали.. а томже товарищ присвоил указателю адресу байтового массива, а переда его в функцию где int * хочетца ... голова что-то плохо с утра варит, но что-то в этом роде


Была определена переменная типа:
struct {
byte field1;
word field2;
dword field3;
} Var;
Судя по всему, сама переменная выравнена по адресу, а вот поле field3 нет. В функцию передается адрес поля field3, который как раз и невыранен, из-за чего происходит глюк!
Как с этим бороться, даже не знаю sad.gif
Go to the top of the page
 
+Quote Post
goodwin
сообщение Aug 6 2006, 18:14
Сообщение #11


Местный
***

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



А вообще-то это зависит от конкретного компилятора - как правило в них имеется прагма для выравнивания элементов структур.
Но в этом случае могут быть нестыковки допустим при передаче структуры по последовательному порту в другое устройство (используя указатель).
Я в MSP так уже натыкался... С тех пор не злю медведя - лучше добавить еще byte в структуру, или на худой конец поместить byte последним.

Действительно, с 86 таких проблем нет - установил выравнивание по границе 1 байт и все...
Go to the top of the page
 
+Quote Post
Andy Mozzhevilov
сообщение Aug 7 2006, 03:22
Сообщение #12


Знающий
****

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



Цитата(abcdefg @ Aug 7 2006, 00:00) *
Цитата(DASM @ Aug 5 2006, 22:18) *

гм.. ну так если Keil - у предложили указатель на void - то как бы чего он выравнивать то будет.... то есть смотря как этот указатель инициализировали.. а томже товарищ присвоил указателю адресу байтового массива, а переда его в функцию где int * хочетца ... голова что-то плохо с утра варит, но что-то в этом роде


Была определена переменная типа:
struct {
byte field1;
word field2;
dword field3;
} Var;
Судя по всему, сама переменная выравнена по адресу, а вот поле field3 нет. В функцию передается адрес поля field3, который как раз и невыранен, из-за чего происходит глюк!
Как с этим бороться, даже не знаю sad.gif


Не должно такого быть, или приведите весь код, включая преобразования типов при обращении к структуре.
Такое ощущение, что вы предварительно накладываете структуру на байтовый буфер, типичная ошибка.


--------------------
Пасу котов...
Go to the top of the page
 
+Quote Post
abcdefg
сообщение Aug 7 2006, 07:52
Сообщение #13


Местный
***

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



Цитата(Andy Mozzhevilov @ Aug 7 2006, 07:22) *
Не должно такого быть, или приведите весь код, включая преобразования типов при обращении к структуре.
Такое ощущение, что вы предварительно накладываете структуру на байтовый буфер, типичная ошибка.


Простейший пример:
struct {
byte field1;
word field2;
dword field3;
} test_str;

dword *ptr1= &(test_str.field3);

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

*ptr1 = 0x00000000; // bug, тут происходит запись в "выравненный адрес"
Go to the top of the page
 
+Quote Post
Harbour
сообщение Aug 7 2006, 09:36
Сообщение #14


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

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



что-то видать намучено в linker script с align опцией - начало структур выравнивается по двойному слову (align 4), т.е. в test_str в середине компилер делает gap. К упакованным структурам применяется более медленная побайтовая адресация.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Aug 7 2006, 10:00
Сообщение #15


Гуру
******

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



Цитата(Harbour @ Aug 7 2006, 12:36) *
что-то видать намучено в linker script с align опцией

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


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
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
Сергей Борщ
сообщение Aug 10 2006, 15:14
Сообщение #31


Гуру
******

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



Цитата(GetSmart @ Aug 10 2006, 16:30) *
Ну допустим. Тогда как проще (и желательно красивее) всего прочитать число допустим float с байтового адреса?
На ум пришло такое:
Код
float val;
#pragma pack (push,1)
typedef struct {
   float  data;
}packed_float_t;
#pragma pack(pop)
float = ((packed_float_t *)getAddr())->data;
float = (*(packed_float_t *)getAddr()).data;

но не проверял. Если попробуешь, сообщи результат.


--------------------
На любой вопрос даю любой ответ
"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 11 2006, 02:03
Сообщение #32


.
******

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



Сергей Борщ
Именно так я извратился ещё вчера. (в смысле float = ((packed_float_t *)getAddr())->data;)
Но скомпиленный код получился ужасный. Хотя корректный.

Через memcpy тоже вобщем нормально. Точнее не хуже этого.

Странно ещё то, что компилятор даже warning не выдал когда скомпилил мой приведённый отрывок. Мало того, неправильно его скомпилил, так ещё я подумал что он достаточно умный чтоб не ошибиться. На мой взгляд это какая-то недоработка.


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


Йа моск ;)
******

Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610



Ну есть еще злой способ:
Код
float getfloat(char *p)
{
#pragma pack(1)
union
{
  float x;
  struct
  {
    char c1;
    char c2;
    char c3;
    char c4;
  };
};
#pragma pack()
c1=*p++;
c2=*p++;
c3=*p++;
c4=*p;
return(x);
}

В иаре точно стрельнет, в остальных - скорее всего надо именовать юнион и структуру, что не меняет идеи wink.gif

Сообщение отредактировал Rst7 - Aug 11 2006, 05:15


--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Aug 11 2006, 08:16
Сообщение #34


Гуру
******

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



Цитата(GetSmart @ Aug 11 2006, 05:03) *
Сергей Борщ
Именно так я извратился ещё вчера. (в смысле float = ((packed_float_t *)getAddr())->data;)
Говорят, "у дураков мысли сходятся" :-) Однако продолжение почему-то забывают: "но у умных - чаще!"
Цитата
Странно ещё то, что компилятор даже warning не выдал когда скомпилил мой приведённый отрывок. Мало того, неправильно его скомпилил, так ещё я подумал что он достаточно умный чтоб не ошибиться. На мой взгляд это какая-то недоработка.
Вроде у Страуструпа читал, что если уж используешь явное преобразование указателей - сам смотри. Ведь в зависимости от контекста этот код может быть как абсолютно правильным (если этот char * в прошлой жизни был float *) и тогда предупреждения компилятора будут мешать или неправильным как в твоем случае. Видимо, придется просто запомнить, что в подобных случаях могут быть грабли.


--------------------
На любой вопрос даю любой ответ
"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

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

 


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


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