iShustov 0 5 августа, 2006 Опубликовано 5 августа, 2006 · Жалоба есть команда STR R1, [R0, #0x0] при R1 = 0x00000000, R0 = 0x400002B5 пишет нули по адресу 0x400002B4 !!! Есть ли выравнивание по адресу записи?! Если это так, то надо аккуратно работать в keil'e с void-скими указателями :( Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DASM 0 5 августа, 2006 Опубликовано 5 августа, 2006 (изменено) · Жалоба есть команда STR R1, [R0, #0x0] при R1 = 0x00000000, R0 = 0x400002B5 пишет нули по адресу 0x400002B4 !!! Есть ли выравнивание по адресу записи?! Если это так, то надо аккуратно работать в keil'e с void-скими указателями :( 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 тут не причем - архитектура однако Изменено 5 августа, 2006 пользователем DASM Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 2 5 августа, 2006 Опубликовано 5 августа, 2006 · Жалоба И Keil тут не причем - архитектура однако С архитектурными ограниченими дело ясное. Но если Keil вдруг сваял такой ассеблерный код из вполне внятного "C", то он "причем" :-(. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DASM 0 5 августа, 2006 Опубликовано 5 августа, 2006 (изменено) · Жалоба И Keil тут не причем - архитектура однако С архитектурными ограниченими дело ясное. Но если Keil вдруг сваял такой ассеблерный код из вполне внятного "C", то он "причем" :-(. гм.. ну так если Keil - у предложили указатель на void - то как бы чего он выравнивать то будет.... то есть смотря как этот указатель инициализировали.. а томже товарищ присвоил указателю адресу байтового массива, а переда его в функцию где int * хочетца ... голова что-то плохо с утра варит, но что-то в этом роде Изменено 5 августа, 2006 пользователем DASM Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Rst7 5 6 августа, 2006 Опубликовано 6 августа, 2006 · Жалоба есть команда STR R1, [R0, #0x0] при R1 = 0x00000000, R0 = 0x400002B5 пишет нули по адресу 0x400002B4 !!! Есть ли выравнивание по адресу записи?! Если это так, то надо аккуратно работать в keil'e с void-скими указателями :( А что вас так испугало? Читаем описание инструкции 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 такое не прокатит, дата аборт сразу... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 2 6 августа, 2006 Опубликовано 6 августа, 2006 · Жалоба А что вас так испугало? Очевидно получение неожиданного и без всяких предупреждений результата на ARM платформе (в отличие , например, от x86 платформы на которой обращение по невыровненному адресу хоть и медленнее, но корректно выполнится). И необходимость держать такой "нюанс" в голове программиста. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Rst7 5 6 августа, 2006 Опубликовано 6 августа, 2006 · Жалоба А что вас так испугало? Очевидно получение неожиданного и без всяких предупреждений результата на ARM платформе (в отличие , например, от x86 платформы на которой обращение по невыровненному адресу хоть и медленнее, но корректно выполнится). И необходимость держать такой "нюанс" в голове программиста. Ну как сказать - неожиданный, на 68000 - аналогично, правда там exception и при записи происходит (а вот начиная с 030 - уже работает невыровненный доступ), PPC - тоже отказывается работать с невыровненными данными, да пожалуй все RISC такие; из классики - PDP11 - тоже самое, IBM360/370 - тоже, вот VAX - не помню. Так что x86 реально в меньшенстве... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 2 6 августа, 2006 Опубликовано 6 августа, 2006 · Жалоба Так что x86 реально в меньшенстве... Но не по привычности/распространенности. Да ведет себя 'правильнее' в данной ситуации. Давить? :-))) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Rst7 5 6 августа, 2006 Опубликовано 6 августа, 2006 (изменено) · Жалоба Давить? :-))) Что??? Куда??? Да и это вам привычней, а нам нет ;) Изменено 6 августа, 2006 пользователем Rst7 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
iShustov 0 6 августа, 2006 Опубликовано 6 августа, 2006 · Жалоба гм.. ну так если Keil - у предложили указатель на void - то как бы чего он выравнивать то будет.... то есть смотря как этот указатель инициализировали.. а томже товарищ присвоил указателю адресу байтового массива, а переда его в функцию где int * хочетца ... голова что-то плохо с утра варит, но что-то в этом роде Была определена переменная типа: struct { byte field1; word field2; dword field3; } Var; Судя по всему, сама переменная выравнена по адресу, а вот поле field3 нет. В функцию передается адрес поля field3, который как раз и невыранен, из-за чего происходит глюк! Как с этим бороться, даже не знаю :( Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
goodwin 0 6 августа, 2006 Опубликовано 6 августа, 2006 · Жалоба А вообще-то это зависит от конкретного компилятора - как правило в них имеется прагма для выравнивания элементов структур. Но в этом случае могут быть нестыковки допустим при передаче структуры по последовательному порту в другое устройство (используя указатель). Я в MSP так уже натыкался... С тех пор не злю медведя - лучше добавить еще byte в структуру, или на худой конец поместить byte последним. Действительно, с 86 таких проблем нет - установил выравнивание по границе 1 байт и все... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Andy_Mozzhevilov 0 7 августа, 2006 Опубликовано 7 августа, 2006 · Жалоба гм.. ну так если Keil - у предложили указатель на void - то как бы чего он выравнивать то будет.... то есть смотря как этот указатель инициализировали.. а томже товарищ присвоил указателю адресу байтового массива, а переда его в функцию где int * хочетца ... голова что-то плохо с утра варит, но что-то в этом роде Была определена переменная типа: struct { byte field1; word field2; dword field3; } Var; Судя по всему, сама переменная выравнена по адресу, а вот поле field3 нет. В функцию передается адрес поля field3, который как раз и невыранен, из-за чего происходит глюк! Как с этим бороться, даже не знаю :( Не должно такого быть, или приведите весь код, включая преобразования типов при обращении к структуре. Такое ощущение, что вы предварительно накладываете структуру на байтовый буфер, типичная ошибка. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
iShustov 0 7 августа, 2006 Опубликовано 7 августа, 2006 · Жалоба Не должно такого быть, или приведите весь код, включая преобразования типов при обращении к структуре. Такое ощущение, что вы предварительно накладываете структуру на байтовый буфер, типичная ошибка. Простейший пример: 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, тут происходит запись в "выравненный адрес" Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Harbour 0 7 августа, 2006 Опубликовано 7 августа, 2006 · Жалоба что-то видать намучено в linker script с align опцией - начало структур выравнивается по двойному слову (align 4), т.е. в test_str в середине компилер делает gap. К упакованным структурам применяется более медленная побайтовая адресация. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 2 7 августа, 2006 Опубликовано 7 августа, 2006 · Жалоба что-то видать намучено в linker script с align опцией Linker тут практически ни причем, поскольку оперирует линковкой сегментов. Ну а компилятор - в данном контексте имел возможность отругаться и не выдавать из пакованной структуры смещенный адрес dword. Никаких передач через void * или преобразования типов нет, все явно указано - мог, как минимум, предупредить. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться