问题标签 [red-zone]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
1601 浏览

c - 在 x86 平台中使用 -mcmodel=kernel 标志

我正在尝试将针对 x86 架构构建的设备驱动程序交叉编译到 arm 平台。它编译时没有任何错误,但我不认为所有功能都可用。所以我检查了makefile并找到了这个特定的部分。

这似乎是唯一依赖于架构的部分。在谷歌上一段时间后,我发现 -mcmodel=kernel 用于内核代码模型,而 -mno-red-zone 是为了避免在内存中使用红色区域,它们都是针对 x86_64 的。但我不清楚,它将 cmodel 设置为内核有什么影响?

(也非常感谢您对 arm 问题的任何见解。)

0 投票
2 回答
486 浏览

assembly - 为什么编译器保留一点堆栈空间而不是整个数组大小?

以下代码

编译成这样:

知道整数是 4 个字节,数组大小为 120,数组应该占用 480 个字节,但从 ESP 中只减去 360 个字节......这是为什么呢?

0 投票
0 回答
38 浏览

assembly - 组装:我不明白为什么堆栈指针似乎(!)在这里保留不足的内存

我是一个组装初学者,所以我的问题的答案对你们大多数人来说可能是完全显而易见的,但对我来说不是。请不要责备。

在 64 位系统上,此 C 代码:

产生这个汇编代码:

我希望堆栈指针至少保留 230 个字节(可能更多),以便可以将“ary”(第 3 行)存储在其中。但在第 9 行,堆栈指针仅递减 120 个字节。这会在基指针 rbp 和 [rbp-120] 之间产生一个 120 字节的缓冲区。这对于“ary”(230 字节)来说太小了。从第 10 行可以看出,ary-index '0' 存储在 [rbp-240] 处,它在基指针下方 240 字节处,因此在缓冲区下方 120 字节处,缓冲区在 [rbp- 120]。所以看起来好像'ary'的一部分存储在缓冲区之外。

当然不是编译器感到困惑,但我很困惑。所以我的问题是:我在这里误解了什么?也许在第 9 行它不是 120 字节,而是 120 * WORD(120 * 2 字节 = 240 字节,适合什么)?这意味着我们在这里混合了一个字节数(第 10 行)和一个字数(第 9 行)。那么我的问题是,如果一个数字是字节数、字数、双字数……,我怎么能在汇编中看到?当然,在第 10 行它被指定为 'BYTE',但是第 9 行呢?

谢谢你的回答!

0 投票
0 回答
469 浏览

c++ - 为什么 x64 上的函数 Epilog 中没有“离开”指令?

我正在了解堆栈如何在 x86 和 x64 机器上工作。然而,我观察到的是,当我手动编写代码并对其进行反汇编时,它与我在人们提供的代码中看到的不同(例如,在他们的问题和教程中)。这是一个小例子:

资源

x86

现在去 x64

如您所见,我的主要困惑是当我针对 x86 进行编译时 - 我看到了我的期望。当它是 x64 时 - 我错过了离开指令或确切的以下序列:mov rsp, rbp然后pop rbp. 穿什么?

更新

它似乎leave丢失了,只是因为它以前没有被改变过。但是,还有另一个问题——为什么框架中没有本地变量的分配?


对于这个问题@melpomene给出了非常简单的答案 - 因为“红色区域”。这基本上意味着不调用其他函数(叶)的函数可以使用堆栈下方的前 128 个字节而无需分配空间。因此,如果我在 an 内插入add()对任何其他哑函数的调用 -sub rsp, X并将add rsp, X分别添加到序言和结尾。

0 投票
0 回答
37 浏览

c - 组装奇怪的堆栈使用

关于如何在 Assembly 中使用堆栈,我几乎没有疑问。据我所知,%rsp 寄存器用作堆栈指针。要在汇编代码中在堆栈上分配新内存,只需从 %rsp 中减去所需的数量,然后将其向后移动。然后,您可以通过向 %rsp 添加特定值来访问新分配的内存。

但是,当我使用 GCC 将 C 代码编译为汇编时,有时会得到奇怪的结果。

当我做一些这样的功能时:

我希望是这样的:

相反,我得到了这个:

它实际上并没有移动堆栈指针,它只是使用它后面的空间。当我传递 7 个参数时,它变得更加奇怪:

现在汇编代码:

在上一个示例之后,我预计代码不会从 %rsp 中减去任何内容。使用较小的地址完全没问题,那里什么都没有。但是 16(%rsp) 呢?它应该指向已经在堆栈中分配的空间,它不会覆盖一些东西吗?

最后但并非最不重要的一点是,如果我编写那个简单的函数:

汇编代码:

如您所见,指向 arr 的指针存储在 -24(%rsp) 到 -16(%rsp) 中。整数 n 存储在 -28(%rsp) 到 -24(%rsp) 中,整数 i 存储在 -4(%rsp) 到 (%rsp) 中。-16(%rsp) 到 -4(%rsp) 之间的空间呢?为什么不用?这背后有什么特别的原因吗?

0 投票
0 回答
137 浏览

c - 了解 C 程序的堆栈和红色区域

这是一个简单的 C 程序:

在 Ubuntu 64 位上使用 GNU 调试器,我从 main 函数的开始逐步调试程序,这是调试器的结果:

正如我们所看到的,在初始化 x 和 ptr 时,堆栈指针在程序期间不会改变。我在网上查到的是x和ptr其实是存放在内存栈段的红色区域的。

然而,让我感到困惑的部分是:首先,我们声明 x 并将其设置为 10。x 的地址是:0x7fffffffdffc。然后我们初始化一个指向 x 的指针 ptr,导致 ptr 与 x 的地址具有相同的值。然而,引起我注意的是指针本身的地址:0x7ffffffffe0f0 比 x 的地址(e0f0-dffc = 4)大 4 个字节,这与我对堆栈的了解相矛盾,它在记忆,而不是向上。
红色区域的行为是否与堆栈不同?

0 投票
2 回答
304 浏览

assembly - 堆栈红色区域的实际大小是多少?

x86-64 System V ABI中,指定后面的空间$rsp - 128是所谓的红色区域,任何信号处理程序都不会触及。在我的机器上

我预计堆栈中只有 2 页。所以我写了下面的程序来测试红色区域可以扩大到多大:

所以我预计程序总是失败。但是程序有时会失败SEGV有时会很好地完成

MAP_GROWSDOWN该行为与文档完全相同:

该标志用于堆栈。它向内核虚拟内存系统指示映射应该在内存中向下扩展。返回地址比进程的虚拟地址空间中实际创建的内存区域低一页。触摸映射下方“保护”页面中的地址将导致映射增长一页。这种增长可以重复,直到映射增长到下一个较低映射的高端页面内,此时触摸“保护”页面将产生SIGSEGV信号。

正如在这个问题中所讨论的,映射是用这种方式创建的MAP_GROWSDOWN并且PROT_GROWSDOWN不会以这种方式增长:

问题:结合上面的推理,唯一使用MAP_GROWSDOWN是否是主线程的[stack]映射?

0 投票
0 回答
87 浏览

assembly - 在 x86_64 中使用 Frame 指针而不是 Stack 指针

使用 GCC 将简单的 C 代码编译成程序集将具有以下输出:

我的问题是,为什么要使用偏移量frame base pointer (rbp)而不是操纵stack pointer (rsp). 这不是拥有堆栈指针的全部意义吗?

如果这个进程的堆栈被其他进程(例如垃圾收集)覆盖,甚至不知道堆栈正在被使用,因为rsp在写入值时不会递减。

0 投票
1 回答
249 浏览

linux - System V ABI的红区是如何实现的

编译器如何确保红色区域没有被破坏?是否有空间过度分配?

什么因素导致选择 128 字节作为红色区域的大小?

0 投票
1 回答
106 浏览

c - C数组的反汇编给出了奇怪的结果

上面的代码产生

当我将代码更改为

生成的程序集是

这仍然很奇怪,因为我不明白为什么它不分配给以前的创作。我在 -O0 运行,所以 gcc 不会优化它。为什么 gcc 为错误大小的数组创建代码?

对于 x86 也是如此

用 -m32 编译给了我:

这额外的 12 个字节来自哪里?为什么 -m32 有 char test[50] 的子指令而 x86_64 没有?