Tag: 堆栈

ARM GCC生成函数序言

我提到ARM工具链可以生成不同的函数序言。 实际上,我看到了两个完全不同的function序言的obj文件(vmlinux): 第一种情况看起来像: push {some registers maybe, fp, lr} (lr ommited in leaf function) 第二种情况看起来像: push {some registers maybe, fp, sp, lr, pc} (i can confuse the order) 所以当我看到第二个推动额外的pc和sp。 另外我在崩溃实用程序(kdump项目)中看到了一些注释,内核堆栈框架应该有格式{…,fp,sp,lr,pc}让我更加困惑,因为我看到在某些情况下它不是真正。 1.)我是否正确需要一些gcc额外的标志来推动额外的pc和sp在functionprolog? 如果是的话他们是什么? 2.)这是用来做什么的? 基本上,据我所知,我可以只用FP和LR展开堆栈,为什么我需要这个额外的值? 3.)如果这个事情与编译标志没有任何关系 – 我怎么能强制生成这个扩展函数prolog,又是什么目的? 谢谢。

分配新的调用堆栈

(我认为这个问题很可能已经重复或者已经在这里回答了,但是由于“堆栈分配”和相关术语的干扰,寻找答案很难。) 我有一个玩具编译器,我一直在研究脚本语言。 为了能够在脚本正在进行时暂停执行并返回到主机程序,它有自己的堆栈:带有“堆栈指针”变量的简单内存块,使用正常的C代码操作递增对于那种事情等等。 到目前为止没有意思。 目前我编译为C.但我也有兴趣调查编译机器代码 – 同时保持二级堆栈和在预定义控制点返回主机程序的能力。 所以…我认为在我自己的代码中使用传统的堆栈寄存器不太可能是一个问题,我假设寄存器会发生什么,只要一切都在我完成时就恢复了(如果我做的话,请纠正我)在这一点上我错了。 但是 ……如果我希望脚本代码调用其他库代码,使用这个“虚拟堆栈”离开程序是否安全,或者是否必须为此目的返回原始堆栈? 像这一个和这一个的答案表明堆栈不是传统的内存块,但它依赖于特殊的,系统特定的行为来处理页面错误和诸如此类的东西。 所以: 将堆栈指针移动到其他内存区域是否安全? 堆栈内存不是“特殊”? 我认为线程库必须做这样的事情,因为它们会创建更多的堆栈…… 假设使用堆栈寄存器和指令操作任何内存区域都是安全的,我可以认为没有理由调用任何具有已知调用深度的函数(即没有递归,没有函数指针)是一个问题,只要这样做金额在虚拟堆栈上可用。 对? 无论如何,堆栈溢出在普通代码中显然是一个问题,但是对于这样的系统中的溢出会有任何额外的灾难性后果吗? 这显然不是必需的,因为简单地将指针返回到实际堆栈将是完全可用的,或者就此而言,首先不要滥用它们并且只是放置更少的寄存器,我可能不应该尝试这样做完全(尤其是因为显然不在我的深处)。 但无论如何我仍然很好奇。 想知道这些事情是如何运作的。 编辑:对不起,当然应该说。 我正在研究x86(我自己的机器为32位),Windows和Ubuntu。 没有异国情调。

它是在堆栈还是堆?

我有一些C代码,这是一个谜题。 出于这个代码的原因,我想知道如何判断struct对象是在堆还是堆栈上? 没有使用malloc或calloc创建对象。 他们以arrays的forms开始他们的生活。 出于本文的目的,我将调用struct Emp。 Emp myEmp[6]; /* Each myEmp[?] item is populated in code */ 对象以各种方式进行排序和操作,在某些时候,对象被复制,然后传递给数组指针。 副本通过memcpy完成。 然后将对象放入类似于: Emp* emps_a[6] 。 对象来自副本并分配到上面的emps_a中。 int i; for( i = 0; i < n; i++ ) { emps_a[i] = myEmpsCopy + i; } 我不确定是否有一些或任何一个与我的问题有关。 我从不需要免费()或记忆清理……我担心我对C不太了解。 非常感谢帮助。

有关堆栈如何在C中工作的说明

我只是想在将数据推送到堆栈时对链接过程进行简单的解释。 我知道如何使用我书中的代码,但是当我将堆栈头链接从一个链接移动到另一个时,我不确定我是否理解该过程如何工作。 对于像这样的堆栈: typedef struct node { void dataptr; struct node* link; }STRUCT_NODE; typedef struct { int count; STACK_NODE* top; }STACK; 如何更改链接以指向堆栈上推送的新数据。 我也不知道

什么在堆栈内?

如果我运行程序,就像 #include int main(int argc, char *argv[], char *env[]) { printf(“My references are at %p, %p, %p\n”, &argc, &argv, &env); } 我们可以看到这些区域实际上在堆栈中。 但还有什么呢? 如果我们在Linux 3.5.3中运行所有值的循环(例如,直到segfault),我们可以看到一些奇怪的数字,以及由一堆零分隔的两个区域的种类,可能是为了防止覆盖环境变量偶然。 无论如何,在第一个区域必须有很多数字,例如每个函数调用的所有帧。 我们怎样才能区分每个帧的结尾,参数在哪里,如果编译器添加了一个金丝雀,返回地址,CPU状态等等?

C中的exception处理 – setjmp()返回0的用途是什么?

我有几个与setjmp / longjmp用法有关的问题 – setjmp(jmp ___ buf stackVariables)返回0的用途是什么。这是默认值,我们无法影响。 setjmp(stackVariables)的唯一意义是在stackVariables中推送堆栈。 并且基本上0告诉我们堆栈是否已成功推送到stack_variables。 当你从longjmp返回时,它们有一次是非零值(任何非零)。 什么是从lomgjmp返回,何时从longjmp返回,处理exception时。 这种设置真的令人困惑。 有些人可以把它与try / throw和catch联系起来。 如果可以提供一些很好的setjmp / longjmp示例,那将会非常棒。 longJmp是throw,并且在可以引发exception的地方之后调用它。 谢谢。

嵌入式软件的调用树

有没有人知道一些工具来为C应用程序创建一个将在微控制器(Cortex-M3)上运行的调用树? 它可以从源代码(非理想),目标代码(首选解决方案)或运行时(可接受)生成。 我看过gprof,但是仍然有很多东西需要它才能在嵌入式系统上运行。 另外一个好处是该工具还可以提供最大堆栈深度。 更新:解决方案最好是免费的。

将指向本地变量的指针传递给函数:它安全吗?

例如: void func1(){ int i = 123; func2(&i); } void func2(int *a){ *a = 456; } 当func1调用func2 ,一个指向局部变量的指针被传递给func2 – 指针指向堆栈。 这对C的规则是否安全? 谢谢。

黑客挑战 – 在代码中查找漏洞

我的朋友最近完成了一次黑客挑战并将其发送给我(二进制和源代码)。 我之前想问他提示,因为我想自己做:) 我一直在经历它,但我正在努力找到这个漏洞。 #include #include #include #include static void usage(const char *argv0) { printf(“Build your own string!\n”); printf(“\n”); printf(“Usage:\n”); printf(” %s length command…\n”, argv0); printf(“\n”); printf(“Each command consist of a single character followed by it’s index.\n”); printf(“\n”); printf(“Example:\n”); printf(” %s 11 h0 e1 l2 l3 o4 w6 o7 r8 l9 d10\n”, argv0); exit(1); } int […]

某个程序的堆栈内存有多大,是否有可以设置它的编译器标志?

正如标题所述:关于堆栈的大小是否有任何一般的“经验法则”。 我猜测大小会有所不同,具体取决于操作系统,体系结构,缓存大小,可用RAM数量等。 但是一般可以说什么,或者有没有办法找出,有多少堆栈, 这个程序是允许使用的? 作为一个额外的问题是有任何方式(使用编译器标志等(在这里主要考虑C / C ++,但也更通用))堆栈的大小可以由用户设置为固定大小? 顺便说一句,我严格要求出于好奇,我没有堆栈溢出。 🙂