有人可以向我解释下面发生了什么吗? 问题:
movl $0x5,-0x4(%rbp)
; %
和negative 0x4
是什么意思?int main(int argc, char* argv[])
{
int i = 5; // line 25
i ++; // line 26
}
-----------------------------------------------------
Disassembly:
25 int i = 5;
00000000004014f4: movl $0x5,-0x4(%rbp)
26 i ++;
00000000004014fb: addl $0x1,-0x4(%rbp)
-----------------------------------------------------
Register Values:
rbp: 0x23fe60
-----------------------------------------------------
Memory map at line 25:
Address | 0-3 | 4-7 | 8-B | C-F |
0x23fe60 |00000000|00000000|00000000|05000000|
Memory map at line 26:
Address | 0-3 | 4-7 | 8-B | C-F |
0x23fe60 |00000000|00000000|00000000|06000000|
注意:上面是由Eclipse生成的,我在64位机器上使用mingw进行编译。
答案 0 :(得分:3)
因为你的编译器不喜欢它。它决定将变量i
放在堆栈上。
rbp
不包含内存缓存的地址。 rbp
是基本指针,它指向堆栈的底部。 -0x4(%rbp)
是变量i
在内存中(堆栈上)的位置。它表示rbp MINUS 4 的值。为什么4?因为i
需要4个字节。所以 是i
的地址。
请参阅http://en.wikibooks.org/wiki/X86_Disassembly/The_Stack
movl $0x5,-0x4(%rbp)
; %
和negative 0x4
的含义是什么? 有两种常见的汇编语法
遗憾的是,您的代码位于AT& T. %
是AT& T语法中引用变量的方式。 -0x4
是数字-4
的十六进制表示(请参阅上面的答案)。
请参阅http://en.wikipedia.org/wiki/X86_assembly_language#Syntax
答案 1 :(得分:2)
没有'缓存地址' - 缓存是从程序中抽象出来的,只有CPU和操作系统知道缓存以及如何将内存地址转换为缓存地址'
变量i在堆栈上分配。 rbp是框架的基本指针'它指向当前函数在堆栈上执行的帧。所以-0x4(%rbp)
意味着在偏移量4(向后 - 后来回到那个点)到寄存器rbp,变量i被定位。
详细了解堆栈的工作原理及其框架的外观:http://www.cs.umd.edu/class/sum2003/cmsc311/Notes/Mips/stack.html
movl $0x5,-0x4(%rbp)
是有效的,你是对的,看起来很奇怪来自英特尔语法世界。但实际上这是AT& T语法代码的一个例子。请阅读此处以获取进一步说明:http://en.wikipedia.org/wiki/X86_assembly_language#Syntax
我真的认为你会从阅读中受益:http://lwn.net/Articles/250967, 在思考大图片时,它确实给了我很多帮助。关于记忆。
答案 2 :(得分:2)
你的意思是“不在登记簿中吗?”因为您的程序没有使用高优化设置进行编译(但如果您使用高优化值编译,则整个过程将为空,因为它不会“执行任何操作”(没有副作用)。包含您的变量的地址肯定会是当CPU执行这些指令时引入内存缓存
register rbp包含函数堆栈框架的基础,它是从中分配本地自动变量的地方,这是由您的语言的调用约定指定的。
在这种情况下,mov指令是立即值到内存位置的移动。 %作为注册名称的前缀。由于堆栈传统上向下增长,因此本地自动变量的偏移量是从帧/堆栈的底部开始的负偏移量。
答案 3 :(得分:0)
这是编译器的决定。在过去,人们会使用关键字register
向编译器提供经常使用该变量的提示,以便编译器可以使用该字段的寄存器而不是堆栈条目。现在不建议这样做,因为编译器现在非常聪明,并且通常会比我们更好地进行优化。
在输入函数时,局部变量将被压入堆栈。在此rbp之后将设置为rsp的值,即堆栈指针。当rsp指向下一个空闲空间时,rbp也是如此,所以你需要-4来获取推送到堆栈的最后一个变量的地址,在本例中为i
。
将值0x5放入地址rbp-4。