Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 堆栈指针指向保留内存_C_Assembly_Embedded_Stack Pointer - Fatal编程技术网

C 堆栈指针指向保留内存

C 堆栈指针指向保留内存,c,assembly,embedded,stack-pointer,C,Assembly,Embedded,Stack Pointer,我正在调试来自Infineon(汇编语言)的Tricore TC275上的加密实现代码 调用mac函数后,堆栈指针a[10]始终指向保留内存区域 ###### typedefs ###### typedef uint16_t limb_t; typedef limb_t gf_t[DIGITS]; //DIGITS=312 typedef int32_t dslimb_t; ################################ /**Multiply and accumulate

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

调用mac函数后,堆栈指针a[10]始终指向保留内存区域

###### 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)
这段代码在我的主机上运行,但在我的tricore微控制器上,它在第一次mac()函数调用中失败

由于之前的“堆栈指针”
a10
0xD0000600
,堆栈在此平台上向下生长,分配给此区域的内存芯片从
0xD0000000
=>开始,您只有0x600字节的堆栈内存可用于局部变量和其他函数调用(及其局部变量!)

有人知道我可能做错了什么吗

但您正试图分配0x9C0字节(对于
b
c
再加上几个字节,除非这些字节以寄存器结尾,并且优化器足够聪明,不会为它们分配堆栈空间),这会导致超出设计的内存区域,并且首先写入指令会崩溃。实际上,如果您要请求更多的字节,您可能会意外地在草稿行RAM内部启动(生成的地址非常接近
0xc000000
),那么一旦代码离开草稿行区域,代码将在清除阵列时崩溃

但是生成的汇编代码试图在第5行中执行吗

生成的代码不会检查C中的内存可用性,与此类问题相关,C是“不安全”的编程语言,程序员+维护人员/操作员有责任构建代码并在堆栈有足够空间的环境中运行。或者将检查添加到动态代码中,这样就不可能在开发过程中评估堆栈的使用情况,代码应该优雅地处理满堆栈的情况

我还尝试使用calloc在堆上分配内存(而不是像上面的代码那样在堆栈上分配内存),但程序仍然崩溃

这似乎是另一个问题,或者您也有完整的堆(从注释“heap应该是4k”-听起来像是非常小的堆,可能您已经用其他动态分配耗尽了它,而且碎片可能会阻止内存分配器为您的阵列返回连续有效的3k块)。当池耗尽时,堆分配器倾向于返回
NULL
,但可能您的平台非常有限,以至于内存分配器在实现中缺少这样的安全代码,从而使其更小

我还将行dslimb_t acum[2*位]={0}复制到程序的开头,在那里执行时没有出现错误

然后是全局变量,它被放入类似
.data
的段中,该段被放入足够大的内存区域中

是的,624个32位整数至少需要2496(624*4)字节的内存(在C语言中,您通常为抽象支付零成本,因此在本例中,任何一块2496字节长的内存(根据您的平台要求排列)都足以实现这一点,在Java等其他语言中,这样的数组的总成本要高得多,因为还有GC管理和数组管理数据,因此您可以(此类平台上需要大约3000-3500字节)


通常,当一个人在如此多的受限系统上开发时(要求为本地人提供3k的堆栈空间听起来在桌面/网络编程世界中完全可以忽略不计,但在小型嵌入式系统或可能占用大量内存的旧8/16位计算机上),这可能有助于以“数据驱动”的方式设计代码和算法方法,即完全规划内存使用情况,包括代码所在的位置(以及它的大小)、局部/全局变量所在的位置,以及在代码的所有状态下运行所需的最大堆栈

您可以首先检查堆栈为何如此低——“本地数据RAM”似乎约为110k大,因此您可能有足够的空间,并且在构建过程中可以选择调整堆栈大小(或者可以调整链接器脚本)

实际上,您应该检查您的整个内存消耗设计,即您真正需要在内存中包含哪些数据,这些数据在哪里,哪些是临时的,它们的生命周期是什么,等等(至少粗略估计为千字节),并对照芯片上的物理可用内存进行检查,这样您就可以了解编写代码时有多粗心大意,或者如果您的特定任务的内存已经不足,甚至在开始实现之前。(您可以先检查链接器映射文件,查看生成了多少代码,以及
.data/.bss/.rodata/etc
部分中的固定变量有多大,然后检查所有局部变量和堆分配)

然后可能会在某种结构中分配所需的内存。你甚至需要任何动态分配吗?难道你不能简单地将代码中已经存在的整个
.data
段设计为几个全局
struct
变量,按所属的抽象对各种数据进行分组,并在其他代码中使用这些全局变量,而不需要任何动力吗有没有ic分配


此外,如果您正在编写某种库/支持功能,请确保您没有耗尽平台的所有资源,否则不清楚如何在实际任务中使用您的功能。:)

因此624*4=2496字节被分配或什么?除非编译目标是64位。然后将其加倍。您能显示生成此assy节的C代码吗?如果调用前
a10
是“堆栈指针”,它是
0xD0000600
,并且您想要2496字节,那么您运气不好,因为只剩下0x600字节(1536字节)。你必须将局部变量移动到内存的其他部分。通常,在这种受约束的系统上,一个人会在算法旁边设计整个内存消耗/使用情况,并有某种内存映射,然后C代码会减少
###### 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)
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);
}