путаница в выравнивании данных ARM9 - PullRequest
3 голосов
/ 06 октября 2011

Рассмотрим следующую программу на C:

int main(void)
{
    char string[10] __attribute__ ((aligned(32)));
    int i;
    int *intp = (int*)(string + 1 );

    printf("string: 0x%x, intp: 0x%x\n", string, intp);

    for (i=0; i<10; i++)
    {
        string[i] = 10;
    }
    dump(string);

    printf("*intp: 0x%x\n", *intp);

    *intp = 0xEEEEEEEE;
    dump(string);

    return 0;
}

Так что я в основном заставлял ЦП обращаться к 32-битным данным (int) по смещенному адресу. TBH Я надеялся на segfault на моей плате ARM9. Но вместо этого я получил интересный / запутанный результат:

После установки intp равным 0xEEEEEEEE, вывод строки показывает:

 0xee, 0xee, 0xee, 0xee, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa    

Таким образом, код фактически изменил первый элемент в строке! Почему?

Спасибо

1 Ответ

5 голосов
/ 06 октября 2011

Скорее всего, процессор "округляет" смещенные адреса, так что когда вы передаете смещенный адрес определенной инструкции, аппаратное обеспечение находит ближайшую границу и выполняет назначенную операцию с этим адресом.

Это может действительно ответить на ваш вопрос:

В ARM и StrongArm, если вы запрашиваете невыровненное слово и не берете ловушку выравнивания, то вы получаете выровненное словоповернута так, что запрашиваемое выравнивание байтов находится в LSB.Например,

Consider:
        Address: 0  1  2  3  4  5  6  7
        Value  : 10 21 66 23 ab 5e 9c 1d

Using *(unsigned long*)2 would give:
        on x86: 0x5eab2366
        on ARM: 0x21102366
...