- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
这个问题是关于 x86 汇编的,但我用 C 提供了一个例子,因为我试图检查 GCC 在做什么。
当我遵循各种汇编指南时,我注意到人们,至少是我阅读过的 Material 中的少数人,似乎习惯于将堆栈变量分配为更接近 rsp 而不是 rbp。
然后我检查了 GCC 会做什么,它似乎是一样的。
在下面的反汇编中,首先保留 0x10 个字节,然后调用 Leaf 的结果通过 eax 到 rbp-0xc,常量值 2 到 rbp-0x8,在 rbp-0x8 和 rbp 之间为变量“q”留出空间。
我可以想象在另一个方向上做它,首先在 rbp 处分配一个地址,然后在 rbp-0x4 处,即在 rbp 到 rsp 的方向上进行,然后在 rbp-0x8 和 rsp 之间留一些空间用于“q”。
我不确定的是,我所观察到的事物是否应该是因为我更好地意识到并坚持的一些架构限制,还是纯粹是这种特定实现的产物以及人们习惯的表现我读到的代码我不应该赋予任何意义,例如这需要在一个方向或另一个方向上完成,只要一致,哪个方向无关紧要。
或者,也许我现在只是在阅读和编写琐碎的代码,而这将是双向的,因为我会在一段时间内获得更重要的东西?
我只想知道我应该如何在我自己的汇编代码中处理它。
所有这些都在 Linux 64 位,GCC 版本 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04) 上进行。谢谢。
00000000000005fa <leaf>:
5fa: 55 push rbp
5fb: 48 89 e5 mov rbp,rsp
5fe: b8 01 00 00 00 mov eax,0x1
603: 5d pop rbp
604: c3 ret
0000000000000605 <myfunc>:
605: 55 push rbp
606: 48 89 e5 mov rbp,rsp
609: 48 83 ec 10 sub rsp,0x10
60d: b8 00 00 00 00 mov eax,0x0
612: e8 e3 ff ff ff call 5fa <leaf>
617: 89 45 f4 mov DWORD PTR [rbp-0xc],eax ; // <--- This line
61a: c7 45 f8 02 00 00 00 mov DWORD PTR [rbp-0x8],0x2 ; // <-- And this too
621: 8b 55 f4 mov edx,DWORD PTR [rbp-0xc]
624: 8b 45 f8 mov eax,DWORD PTR [rbp-0x8]
627: 01 d0 add eax,edx
629: 89 45 fc mov DWORD PTR [rbp-0x4],eax
62c: 8b 45 fc mov eax,DWORD PTR [rbp-0x4]
62f: c9 leave
630: c3 ret
这是C代码:
int leaf() {
return 1;
}
int myfunc() {
int x = leaf(); // <--- This line
int y = 2; // <-- And this too
int q = x + y;
return q;
}
int main(int argc, char *argv[]) {
return myfunc();
}
我如何编译它:
gcc -O0 main.c -o main.bin
我如何拆卸它:
objdump -d -j .text -M intel main.bin
最佳答案
它产生零差异,对必须存在的局部变量做任何你想做的事情(因为你不能将它们优化到寄存器中)。
GCC 正在做的事情的重要性为零;未使用的间隙在哪里(由于堆栈对齐而存在)并不重要。在这种情况下,它是 [rsp]
处的 4 个字节,又名 [rbp - 0x10]
.[rbp - 4]
处的 4 个字节用于 q
.
此外,您没有告诉 GCC 进行优化,因此没有理由期望它的选择甚至是最佳的或有用的学习指南。 -O3
与 volatile int
本地人会更有意义。 (但由于没有任何重要的事情发生,实际上仍然没有帮助。)
重要的事情:
gcc -fomit-frame-pointer
)的小(有符号 8 位)位移1。call
存储到此函数的返回地址)。堆栈通常在缓存中很热,但是如果在较早的加载/存储之后完成,随着堆栈内存的增长接触新的堆栈内存缓存行的影响会稍微小一些。乱序 exec 有望很快获得那些稍后的存储指令,并将缓存未命中存储进入管道以尽早启动 RFO(读取所有权),从而最大限度地减少早期负载阻塞存储缓冲区所花费的时间。call
之前有未使用的堆栈对齐空间,通常最多只有8个字节。这比缓存线小得多,因此对局部变量的空间局部性没有任何显着影响。您知道堆栈指针相对于 16 字节边界的对齐方式,因此在堆栈帧的顶部或底部保留填充的选择永远不会对是否可能触及新的缓存缓存行产生影响。
[rsp + disp8]
)中的比较这就是 x86-64 System V ABI 选择 128 字节的原因
red-zone RSP 下方:它最多提供约 256 字节的空间,可以使用更紧凑的代码大小访问,包括红色区域加上 RSP 上方的保留空间。
关于assembly - 布置堆栈变量开始比 rbp 更接近 rsp 的意义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63817094/
考虑以下几点: ammarfaizi2@integral:/tmp$ vi test.c ammarfaizi2@integral:/tmp$ cat test.c extern void use_b
您可以阅读有关 64 位调用约定的信息 here . x64 函数应该自行清理,但是,当我从 .asm 调用 malloc 时,它会覆盖 RSP 和 RSP+8 处的值。这似乎是非常错误的。有什么建议
使用ptrace获取另一个进程的寄存器时,有没有可能是停止点在内核空间(做系统调用之类的在sleep()),RIP在内核代码段,RSP是内核堆栈指针? 最佳答案 is it possible ...
有问题Compilers: Understanding assembly code generated from small programs编译器使用两个局部变量而不调整堆栈指针。 不调整 RSP
有问题Compilers: Understanding assembly code generated from small programs编译器使用两个局部变量而不调整堆栈指针。 不调整 RSP
我无法理解堆栈的工作原理。首先是我的小代码: void func1 ( int z ) { int i = 1; } int main ( ) { func1 ( 89 ); return
我第一次学习汇编语言。这是(gdb)反汇编的一部分: mov $0x131,%eax cmp 0x8(%rsp),%eax //Question here, what is the va
有人告诉我,如果我使用 rsp 作为通用寄存器,操作系统可能会将寄存器转储到它在中断时指向的位置,从而导致出现问题的行为。 这是真的吗?如果不是,如果我不需要堆栈,我可以使用 rsp 作为通用寄存器吗
对于我们的一个应用程序,我们在/var/log/messages 中看到了以下提到的几条消息: Sep 18 03:24:23 kernel: application_name[14682] tra
我在 CSharpInteractive.rsp 中看到您可以使用/r 在 GAC 中添加对 DLL 的引用: 如何添加对自己的 DLL 的引用? 我试过 System.Reflection.Asse
让我们采用以下基本 C 函数及其生成的有意未优化的程序集: int main() { int i = 4; return 3; } 它生成以下(未优化的)程序集,这对我来说都很有意义:
我研究了 32 位机器,我知道 sub $12, %esp 与 pop %eax 和 mov $0, %eax 上的三次相同。 但我不知道为什么我们在 x86-64 机器上使用 add $18, %r
下面是我的代码: C代码 // this function might look weird, just for demo purpose void func4(int x, int y, int z
下面是我的代码: C代码 // this function might look weird, just for demo purpose void func4(int x, int y, int z
在汇编中,许多函数以下面的序言开始: 00000001004010e0: main(int, char**)+0 push %rbp 00000001004010e1: main(int,
考虑以下x64 NASM语法程序集: inc qword [rax] inc qword [rcx] inc qword [rdx] inc qword [rbx] inc qword [rsp] i
这个问题是关于 x86 汇编的,但我用 C 提供了一个例子,因为我试图检查 GCC 在做什么。 当我遵循各种汇编指南时,我注意到人们,至少是我阅读过的 Material 中的少数人,似乎习惯于将堆栈变
我是内联汇编的新手。我有以下带有内联汇编的 C 函数。我只是想看看 push %%rbp 和 mov %%rsp, %%rbp 是否实际运行正确。我的功能如下, test_inlineAssembly
我目前正在使用 gcc、gdb 和汇编并试图理解它们。我已经复习了一些教程并掌握了一些关键点。 所以我决定使用一个小的 .c 文件,看了一下结果,有些事情不是很清楚。 这是文件: #include
根据 Intel 在 x64 中的说法,以下寄存器称为通用寄存器(RAX、RBX、RCX、RDX、RBP、RSI、RDI、RSP 和 R8-R15)https://software.intel.com
我是一名优秀的程序员,十分优秀!