gpt4 book ai didi

c - 堆栈指针指向保留的内存

转载 作者:太空狗 更新时间:2023-10-29 16:05:27 24 4
gpt4 key购买 nike

我正在调试来自Infineon(reference汇编语言)的tricore TC275上的加密实现代码。

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)并且阵列accum的长度为 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);
}

这段代码在我的主机上运行,但在我的tricore微控制器上,它在第一次mac()函数调用中失败。

最佳答案

由于“stack pointer”a10以前是0xD0000600并且堆栈在这个平台上向下增长,分配给这个区域的内存芯片从0xD0000000=>开始,因此只有0x600字节的堆栈内存可用于局部变量和其他函数调用(及其局部变量!)是的。
有人知道我在这里做错了什么吗?
但是,您正在尝试分配0x9c0字节(对于bc,再加上一些字节,除非这些字节以寄存器结尾,并且优化器足够聪明,不为它们分配堆栈空间),这将导致超出设计的内存区域,并且首先写指令,然后将崩溃。实际上,如果您需要更多的字节,您可能会意外地在便笺簿RAM中启动(结果地址非常接近0xC0000000),那么一旦代码离开便笺簿区域,它就会在清除数组期间崩溃。
但是生成的程序集代码试图在第5行执行?
生成的代码不会检查C中的内存可用性,与此类问题相关C是“不安全”的编程语言,程序员+维护者/操作员有责任在堆栈有足够空间的环境中构建代码并运行它。或者将检查添加到动态的代码中,这样在开发过程中就不可能评估堆栈的使用情况,并且代码应该能够优雅地处理完整的堆栈情况。
我还尝试使用calloc在堆上分配内存(而不是像上面的代码那样在堆栈上分配内存?)但是程序还是崩溃了。
似乎是不同的问题,或者您也有完整的堆(从注释“heap should be 4k”-听起来像非常小的堆,可能您已经用其他动态分配耗尽了它,而且碎片可能会阻止您的内存分配程序为您的数组返回连续有效的3k块)。堆分配器往往在池耗尽时返回NULL,但可能您的平台非常有限,以至于内存分配器在实现中缺少这样的安全代码,从而使其更小。
我还将dslimb_t accum[2*digits]={0}这一行复制到程序的开头,在那里执行它时没有出现错误。
然后是全局变量,它被放置在类似于.data的段中,这个段被放置在足够大的内存区域中。
是的,624个32位整数至少需要2496(624*4)字节的内存(在C语言中,您通常为抽象付出零代价,因此在这种情况下,任何2496字节长的内存(按照您的平台要求对齐)都足以使这成为可能,在Java等其他语言中,这样的数组的总成本要高得多,因为还有gc内务管理和阵列管理数据,所以您可能需要在这样的平台上计算大约3000-3500字节)。
通常,当一个人在如此多的受限系统上开发时(在桌面/网络编程世界中,要求3K的本地堆栈空间听起来是完全可以忽略的事情,但在小型嵌入式系统或旧的8/16位计算机上,这可能会有助于以“数据驱动”的方式设计代码和算法,也就是说,你完全计划你的内存使用,包括代码驻留在哪里(以及它有多大),本地/全局变量在哪里,并且知道运行代码的所有状态所需要的最大堆栈。
你可以先检查一下为什么堆栈这么低——“本地数据RAM”看起来大约有110K大,所以也许你有足够的空间,在构建过程中有一些调整堆栈大小的选项(或者可以调整链接器脚本)。
实际上,你应该检查你的整个内存消耗设计,即你真正需要在内存中有什么数据,它在哪里,哪些是临时的,它们的生命周期是什么,等等(至少粗略的估计是千字节),并对照芯片上的物理可用内存进行检查,因此,您可以了解如何粗心大意地编写代码,或者如果您的特定任务的内存已经用完,甚至在开始实现之前,就可以知道。(可以从检查链接器映射文件开始,查看生成了多少代码,以及.data/.bss/.rodata/etc部分中的固定变量有多大,然后检查所有本地变量和堆分配)
然后可能在某种结构中分配所需的内存。你甚至需要动态分配吗?难道你不能简单地将代码中已经存在的整个.data段设计为几个全局struct变量,按照它们所属的抽象对各种数据进行分组,并在其他代码中使用这些全局变量,而不需要任何动态分配吗?
另外,如果您正在编写某种库/支持功能,请确保不要耗尽平台的所有资源,否则不清楚如何将您的功能与实际任务一起使用。:)

关于c - 堆栈指针指向保留的内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51517892/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com