Указатель стека указывает на зарезервированную память

Я отлаживаю код для криптографической реализации на Tricore TC275 от Infineon ( справочный язык ассемблера).

PMI_PSPR (wx!p): org = 0xC0000000, len = 24K  /*Scratch-Pad RAM (PSPR)*/ 
DMI_DSPR (w!xp): org = 0xD0000000, len = 112K  /*Local Data RAM (DSPR)*/ 

Указатель стека a[10] всегда указывает на зарезервированную область памяти после вызова функции mac.

###### typedefs ######
typedef uint16_t limb_t;
typedef limb_t gf_t[DIGITS]; //DIGITS=312
typedef int32_t dslimb_t;
################################

/**Multiply and accumulate c += a*b*/
void mac(gf_t c, const gf_t a, const gf_t b)
1: 0xC0000812:   D9 AA 40 9F   LEA     a10,[a10]-0x9C0 //Load eff. addr.
       /*Reference non-Karatsuba MAC */
       dslimb_t accum[2*DIGITS] = {0};
2: 0xC0000816:   40 A2         MOV.AA  a2,a10
3: 0xC0000818:   D2 02         MOV     e2,0x0 //move 0x0 to d2 and d3
4: 0xC000081A:   C5 03 37 40   LEA     a3,0x137 // 0.5*length of accum
5: 0xC000081E:   89 22 48 01   ST.D    [a2+]0x8,e2 //<= fails here
6: 0xC0000822:   FC 3E         LOOP    a3,0xC000081E 
7: 0xC0000824:   40 AF         MOV.AA  a15,a10

###contents of relevant registers###
                 before        after
1: a[10]         D000 0600     CFFF FC40 (not definend in memory map?)
2: a[2]          D000 0A06     CFFF FC40
3: d[2]          0000 0002     0000 0000
3: d[3]          0000 0000     0000 0000 (would have been set to zero too)
4: a[3]          0000 0186     0000 0137 (#of iterations in loop)
5: a[2]          CFFF FC40     (store failed here)
value@CFFF FC40  ???? ????     ???? ???? (write is not allowed I guess)

0x9C0 = 2496 (base10) и длина массива накапливается 624каждый элемент, содержащий int32_t, таким образом 624*4 = 2496 Bytes получить выделение или как?

Но по этому адресу в памяти никакие записи не разрешены, насколько я понимаю карта памяти, которая предоставляется компоновщику... Но сгенерированный код сборки пытается сделать в строке 5?

Кто-нибудь знает, что я могу делать здесь не так? Я также пытался использовать calloc для выделения памяти в куче (вместо стека, как это делает приведенный выше код, верно?), Но программа все еще не работала.

Я также скопировал строку dslimb_t accum[2*DIGITS] = {0} до начала программы, где она была выполнена без ошибок.

Большое спасибо за любую помощь!

РЕДАКТИРОВАТЬ

Mac называется так, единообразные образцы некоторых равномерных случайных чисел

gf_t sk_expanded[DIM],b,c;
for (unsigned i=0; i<DIM; i++) {
    noise(sk_expanded[i],ctx,i);
}
for (unsigned i=0; i<DIM; i++) {
    noise(c,ctx,i+DIM); //noisy elements in c after call
    for (unsigned j=0; j<DIM; j++) {
        uniform(b,pk,i+DIM*j); //uniform random numbers in b after call
        mac(c,b,sk_expanded[j]); //fails here on first call
    }
    contract(&pk[MATRIX_SEED_BYTES+i*GF_BYTES], c);
}

этот код выполняется на моем хост-компьютере, но на моем трехъядерном микроконтроллере происходит сбой при первом вызове функции mac().

1 ответ

Решение

Как указатель стека a10 является 0xD0000600 до, и стек растет на этой платформе вниз, а микросхема памяти, назначенная этой области, начинается с 0xD0000000 => у вас есть только 0x600 байтов стековой памяти для локальных и других вызовов функций (и их локальных!).

Кто-нибудь знает, что я могу делать здесь не так?

Но вы пытаетесь выделить 0x9C0 байт (плюс еще несколько для b а также c, если только они не заканчиваются в регистрах, а оптимизатор достаточно умен, чтобы не выделять для них место в стеке), что приводит к выходу за пределы проектной области памяти, и первая инструкция записи затем вылетает. На самом деле, если вы захотите запросить еще много байтов, вы можете случайно запустить внутри ОЗУ Scratch-Pad (результирующий адрес очень близок к 0xC0000000), тогда код будет сбой во время очистки массива, как только он покинет область блокнота.

Но сгенерированный ассемблерный код пытается сделать в строке 5?

Сгенерированный код не проверяет доступность памяти в C, связанный с такого рода проблемами. C является "небезопасным" языком программирования, и программист + сопровождающий / оператор несут ответственность за создание кода и запуск его в такой среде, где стек есть достаточно места. Или добавьте проверки в код, который настолько динамичен, что невозможно оценить использование стека во время разработки, и код должен корректно обрабатывать ситуации с полным стеком.

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

Похоже, другая проблема, или у вас также полная куча (из комментария "куча должна быть 4k" - это звучит как очень маленькая куча, возможно, вы уже исчерпали ее с другими динамическими распределениями, также фрагментация может помешать вашему распределителю памяти возвращать непрерывный допустимый 3k) блок для вашего массива). Распределители кучи имеют тенденцию возвращаться NULL когда их пул исчерпан, но, возможно, ваша платформа настолько ограничена, что в распределителе памяти отсутствует такой код безопасности при реализации, чтобы сделать его меньше.

Я также скопировал строку dslimb_t contrib [2*DIGITS] = {0} в начало программы, где она была выполнена без ошибок.

Тогда это глобальная переменная, которая помещается в .data-подобный сегмент, который помещается в достаточно большую область памяти.

И да, 624 32-разрядным целым числам требуется как минимум 2496 (624*4) байтов памяти (на языке C вы обычно платите ноль за абстракцию, поэтому в этом случае любой фрагмент памяти длиной 2496 байт, который выровнен так, как требует ваша платформа Это достаточно, чтобы сделать это возможным, в других языках, таких как Java, общая стоимость такого массива значительно выше, так как есть также ведение GC и данные управления массивами, так что вы, вероятно, можете сосчитать около 3000-3500 байт, необходимых на такой платформе).


Обычно, когда кто-то разрабатывает систему в столь ограниченном режиме (запрос 3k стекового пространства для локальных пользователей звучит как нечто совершенно незначительное в мире программирования для настольных компьютеров / веб-приложений, но на небольших встроенных системах или старых 8/16-битных компьютерах, которые могут иметь серьезный объем памяти)), это может помочь в разработке кода и алгоритма "управляемым данными" способом, т.е. вы полностью планируете использование своей памяти, включая то, где находится код (и насколько большим он может быть), где находятся локальные / глобальные переменные, и знать, какой максимальный стек необходим для прохождения всех состояний кода.

Во-первых, вы можете проверить, почему стек настолько низок - "локальная память данных", кажется, имеет размер ~110 КБ, поэтому, возможно, у вас там достаточно места, и во время сборки есть возможность изменить размер стека (или скрипт компоновщика может отрегулироваться).

На самом деле вы должны проверить всю структуру потребления памяти, то есть, какие данные вам действительно нужны в памяти, где они находятся, какие временные и каков их жизненный цикл и т. Д. (По крайней мере, по приблизительным оценкам в килобайтах), и сравнить их с физически доступная память на чипе, так что вы можете понять, насколько небрежно вы можете написать код, или, в конце концов, если у вас уже недостаточно памяти для конкретной задачи, даже до начала реализации. (вы можете начать с проверки файла карты компоновщика, чтобы увидеть, сколько кода генерируется и насколько велики фиксированные переменные в .data/.bss/.rodata/etc разделы, затем проверьте все локальные переменные и выделение кучи)

Тогда, возможно, выделите необходимую память в какой-то структуре. Вам даже нужно динамическое распределение? Разве вы не можете просто спроектировать целый .data сегмент уже в коде, как мало глобальных struct переменные, группирующие различные данные по абстракции, к которой они принадлежат, и используют эти глобальные переменные в другом коде, без какого-либо динамического выделения?

Также, если вы пишете какую-то библиотечную / вспомогательную функцию, убедитесь, что вы не исчерпываете все ресурсы платформы, иначе неясно, как можно использовать ваши функциональные возможности наряду с их реальной задачей.:)

Другие вопросы по тегам