问题标签 [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.
c - 在 x86 平台中使用 -mcmodel=kernel 标志
我正在尝试将针对 x86 架构构建的设备驱动程序交叉编译到 arm 平台。它编译时没有任何错误,但我不认为所有功能都可用。所以我检查了makefile并找到了这个特定的部分。
这似乎是唯一依赖于架构的部分。在谷歌上一段时间后,我发现 -mcmodel=kernel 用于内核代码模型,而 -mno-red-zone 是为了避免在内存中使用红色区域,它们都是针对 x86_64 的。但我不清楚,它将 cmodel 设置为内核有什么影响?
(也非常感谢您对 arm 问题的任何见解。)
assembly - 为什么编译器保留一点堆栈空间而不是整个数组大小?
以下代码
编译成这样:
知道整数是 4 个字节,数组大小为 120,数组应该占用 480 个字节,但从 ESP 中只减去 360 个字节......这是为什么呢?
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 行呢?
谢谢你的回答!
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
分别添加到序言和结尾。
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) 之间的空间呢?为什么不用?这背后有什么特别的原因吗?
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 个字节,这与我对堆栈的了解相矛盾,它在记忆,而不是向上。
红色区域的行为是否与堆栈不同?
assembly - 堆栈红色区域的实际大小是多少?
在x86-64 System V ABI中,指定后面的空间$rsp - 128
是所谓的红色区域,任何信号处理程序都不会触及。在我的机器上
我预计堆栈中只有 2 页。所以我写了下面的程序来测试红色区域可以扩大到多大:
所以我预计程序总是失败。但是程序有时会失败SEGV
,有时会很好地完成。
MAP_GROWSDOWN
该行为与文档完全相同:
该标志用于堆栈。它向内核虚拟内存系统指示映射应该在内存中向下扩展。返回地址比进程的虚拟地址空间中实际创建的内存区域低一页。触摸映射下方“保护”页面中的地址将导致映射增长一页。这种增长可以重复,直到映射增长到下一个较低映射的高端页面内,此时触摸“保护”页面将产生
SIGSEGV
信号。
正如在这个问题中所讨论的,映射是用这种方式创建的MAP_GROWSDOWN
并且PROT_GROWSDOWN
不会以这种方式增长:
问题:结合上面的推理,唯一使用MAP_GROWSDOWN
是否是主线程的[stack]
映射?
assembly - 在 x86_64 中使用 Frame 指针而不是 Stack 指针
使用 GCC 将简单的 C 代码编译成程序集将具有以下输出:
我的问题是,为什么要使用偏移量frame base pointer (rbp)
而不是操纵stack pointer (rsp)
. 这不是拥有堆栈指针的全部意义吗?
如果这个进程的堆栈被其他进程(例如垃圾收集)覆盖,甚至不知道堆栈正在被使用,因为rsp
在写入值时不会递减。
linux - System V ABI的红区是如何实现的
编译器如何确保红色区域没有被破坏?是否有空间过度分配?
什么因素导致选择 128 字节作为红色区域的大小?
c - C数组的反汇编给出了奇怪的结果
上面的代码产生
当我将代码更改为
生成的程序集是
这仍然很奇怪,因为我不明白为什么它不分配给以前的创作。我在 -O0 运行,所以 gcc 不会优化它。为什么 gcc 为错误大小的数组创建代码?
对于 x86 也是如此
用 -m32 编译给了我:
这额外的 12 个字节来自哪里?为什么 -m32 有 char test[50] 的子指令而 x86_64 没有?