crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

 
Ответить в данную темуНачать новую тему
> не работает приведение типов на arm
igor_bogomolov
  опции профиля:
сообщение 29.8.2012, 20:31
Сообщение #1


Профессионал
*****

Группа: Сомодератор
Сообщений: 1215
Регистрация: 22.3.2009
Из: Саратов
Пользователь №: 630

Спасибо сказали: 235 раз(а)




Репутация:   29  


Всем привет.
Понимаю, что название темы кажется странным, но тем не менее...
Имеем такой код (синтетический тест воспроизводящий проблему)

#include <stdlib.h>
#include <stdio.h>

int main()
{
    unsigned int i = 0;
    unsigned char buf1 [13] = {0xAA, 0xAB,  0xAC, 0x01,  0x00, 0x02, 0x00, 0x03,  0x00, 0x04, 0x00, 0x05, 0x00 }; // (см *)

    for (i = 3; i < sizeof(buf1); ++i) {
        printf("%02x:", buf1[i]);
    }
    printf("\n");

    for (i = 3; i < sizeof(buf1); i+=2) {
        printf("%04x:", *(unsigned short *)&buf1[i]);
    }
    printf("\n");

    for (i = 0; i < 4; i++) {
        printf("%04x:", *(unsigned short *)&buf1[i]);
    }
    printf("\n");

    return 0;
}
Компилируем для платформы x86, получаем вполне ожидаемый вывод
Цитата
01:00:02:00:03:00:04:00:05:00:
0001:0002:0003:0004:0005:
abaa:acab:01ac:0001:
Компилирую для arm (-mcpu=arm926ej-s -march=armv5te), получаю следущее
Цитата
01:00:02:00:03:00:04:00:05:00:
01ac:0200:0300:0400:0500:
abaa:abaa:01ac:01ac:


Как можно объяснить такой вывод, и, самое главное, как заставить именно этот код вести себя ожидаемо (как на x86)?

* Важный момент, что размер массива нечётный. При выравнивании 1, если сразу объявить еще один такой же массив и повторить для него те же действия, вывод для него будет отличаться, но всё равно не будет правильным (т.е. таким же как на x86).
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
maint
  опции профиля:
сообщение 30.8.2012, 3:57
Сообщение #2


Участник
**

Группа: Участник
Сообщений: 235
Регистрация: 3.8.2009
Из: Иркутск
Пользователь №: 982

Спасибо сказали: 28 раз(а)




Репутация:   2  


Для выяснения берем и выводим на печать на обоих платформах sizeof(unsigned short).
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
iReset
  опции профиля:
сообщение 30.8.2012, 6:38
Сообщение #3


Участник
**

Группа: Участник
Сообщений: 178
Регистрация: 6.6.2012
Пользователь №: 3414

Спасибо сказали: 23 раз(а)




Репутация:   2  


Дело в выравнивании адресов на ARM. Т.е. каждый тип должен лежать по адресу, кратному его размеру. При невыровненном доступе будут ошибки чтения. При преобразовании char* к ushort* получается именно такая ситуация.
Если тебе действительно нужно такое преобразование, используй memcpy для копирования 2 байт во временную переменную, как бы странно это ни звучало.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
igor_bogomolov
  опции профиля:
сообщение 30.8.2012, 8:26
Сообщение #4


Профессионал
*****

Группа: Сомодератор
Сообщений: 1215
Регистрация: 22.3.2009
Из: Саратов
Пользователь №: 630

Спасибо сказали: 235 раз(а)




Репутация:   29  


Цитата(maint @ 30.8.2012, 4:57) *
Для выяснения берем и выводим на печать на обоих платформах sizeof(unsigned short)
Это я конечно же делал. sizeof(unsigned short) одинаков на обоих платформах и равен 2.

Цитата(iReset @ 30.8.2012, 7:38) *
Дело в выравнивании адресов на ARM. Т.е. каждый тип должен лежать по адресу, кратному его размеру. При невыровненном доступе будут ошибки чтения. При преобразовании char* к ushort* получается именно такая ситуация.
Если тебе действительно нужно такое преобразование, используй memcpy для копирования 2 байт во временную переменную, как бы странно это ни звучало.
Ок, спасибо.
Просто получилась такая ситуация. Разработали некую железку для заказчика с arm'овским процессором на борту. У них есть некий код, который они давно используют и который, якобы (по их мнению), хорошо работает. А на нашей железке этот код не работает, из-за таких вот преобразований, показанных выше. Мне теперь нужно грамотно обосновать, из-за чего такое различие. Иначе считается, что наше оборудование не работает.
Если у тебя есть ссылка на какую-нибудь оф. документацию, где описано такое поведение, было бы очень здорово.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
iReset
  опции профиля:
сообщение 30.8.2012, 9:58
Сообщение #5


Участник
**

Группа: Участник
Сообщений: 178
Регистрация: 6.6.2012
Пользователь №: 3414

Спасибо сказали: 23 раз(а)




Репутация:   2  


Цитата(igor_bogomolov @ 30.8.2012, 9:26) *
Если у тебя есть ссылка на какую-нибудь оф. документацию, где описано такое поведение, было бы очень здорово.

Ссылок, к сожалению, нет.
Быстрый Google-поиск по фразе "unaligned pointer ARM" дал в результате ссылку на оф.сайт ARM - Unaligned pointers. Надеюсь, поможет.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
igor_bogomolov
  опции профиля:
сообщение 30.8.2012, 10:09
Сообщение #6


Профессионал
*****

Группа: Сомодератор
Сообщений: 1215
Регистрация: 22.3.2009
Из: Саратов
Пользователь №: 630

Спасибо сказали: 235 раз(а)




Репутация:   29  


Цитата(iReset @ 30.8.2012, 10:58) *
Ссылок, к сожалению, нет.
И на этом спасибо. На самом деле очень помог, что бы объяснить происходящее.

Я вот такую вот ссылочку (тык) нашел описывающую данную ситуацию.
Может еще кому-нибудь интересно будет.


Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Быстрый ответОтветить в данную темуНачать новую тему
Теги
arm, gcc,


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 28.3.2024, 17:50