Перейти к содержанию
    

Q: знатокам arm-вского ассемблера

есть команда STR R1, [R0, #0x0]

при R1 = 0x00000000, R0 = 0x400002B5

пишет нули по адресу 0x400002B4 !!!

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

есть команда 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 тут не причем - архитектура однако

Изменено пользователем DASM

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

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

Изменено пользователем DASM

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

есть команда 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 такое не прокатит, дата аборт сразу...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Так что x86 реально в меньшенстве...

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

 

Да и это вам привычней, а нам нет ;)

Изменено пользователем Rst7

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

Была определена переменная типа:

struct {

byte field1;

word field2;

dword field3;

} Var;

Судя по всему, сама переменная выравнена по адресу, а вот поле field3 нет. В функцию передается адрес поля field3, который как раз и невыранен, из-за чего происходит глюк!

Как с этим бороться, даже не знаю :(

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А вообще-то это зависит от конкретного компилятора - как правило в них имеется прагма для выравнивания элементов структур.

Но в этом случае могут быть нестыковки допустим при передаче структуры по последовательному порту в другое устройство (используя указатель).

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

 

Действительно, с 86 таких проблем нет - установил выравнивание по границе 1 байт и все...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

Была определена переменная типа:

struct {

byte field1;

word field2;

dword field3;

} Var;

Судя по всему, сама переменная выравнена по адресу, а вот поле field3 нет. В функцию передается адрес поля field3, который как раз и невыранен, из-за чего происходит глюк!

Как с этим бороться, даже не знаю :(

 

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

 

Простейший пример:

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, тут происходит запись в "выравненный адрес"

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

что-то видать намучено в linker script с align опцией - начало структур выравнивается по двойному слову (align 4), т.е. в test_str в середине компилер делает gap. К упакованным структурам применяется более медленная побайтовая адресация.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...