在汇编器AT& t上下文中:Movl在指定的行中有什么作用?
我在C中有一些简单的代码行,并希望将其拆卸:
#include <stdio.h>
int main(){
int i=42;
}
对其进行编译并启动GDB,我根本找不到我的值= 42在相应的位置:
不仅是我得到值0,而且确切的
movl $0x2a, -0x4(%rbp)
含义。我知道0x2a在十六进制中是42,但下一部分对我来说是神秘的。这是否意味着将42保存到寄存器RBP中?那么-0x4呢?我的42:o在哪里?
i have a some simple lines of code in C and wanted to disassemble it:
#include <stdio.h>
int main(){
int i=42;
}
After compiling it and starting gdb, i simply cant find my value=42 in the corresponding place:
Its not just that i get the value 0, but what exactly does
movl $0x2a, -0x4(%rbp)
mean. I know that 0x2a is 42 in hex, but the next part is cryptic to me; should it mean, that 42 gets saved into register rbp ? and what about the -0x4? And where is my 42 :O ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
c中的每个变量要么在内存中获得设置位置(称为 a register 。实际上,编译器通常会在这两个绩效位置之间移动变量。
movl
将32位编号(您的int!)从一个寄存器移至另一寄存不使用寄存器的那一部分。按下
和pop
从堆栈中添加并删除项目。 C编译器通常使用它来保存寄存器。作为调用main()
的函数,您不知道它的作用,以及在所有内存main()
使用后如何清理,这就是为什么它是<代码> main()有责任自行清理,使程序完全按照其开始。 (当然,除了操作的结果外)eax
是一个普通寄存器,通常用于功能结果。使用此背景,让我们以更可读的形式重写您的程序:
按%RBP
移动 堆栈指针堆栈本身(因此,我们可以在所有之后清理所有垃圾存储器)MOV%RSP,%RBP
resize0
,防止main( )
从其他 functions functionsmovl $ 0x2a,-0x4(%rbp)
move42 到堆栈中的第一个插槽(注意:由于int是4个字节大,这实际上是-4个空间!)
mov $ 0x0,%eax
move0
到结果寄存器(eax
)pop%RBP < /code> 清理在我们混乱之后,通过还原旧的堆栈指针。这意味着,即使我们重置堆栈的大小,我们上方的程序仍将完好无损。请记住 - 我们这样做是为了防止
main()
访问其他函数的内存。伟大的!retq
返回并说再见;(如果您想检索
42
,您需要更改代码才能说返回42
,这意味着编译器将在eax
中放置42
,它将被传递给您的朋友上方:)Each variable in C either gets a set position in memory (called the stack) or a register. In fact, the compiler will often move variables between these two places for performance.
MOVL
moves a 32-bit number (your int!) from one register to another, whileMOV
moves an entire register, even if your program doesn't use that part of the register.PUSH
andPOP
add and remove items from the stack. It's often used by the C compiler to save registers. As a function callingmain()
, you have no idea what it does, and how to clean up after all the memorymain()
uses, which is why it ismain()
's responsibility to clean up after itself, leaving the program exactly as it started with it. (except, of course, for the results of the operation)EAX
is a common register, and is typically used for the results of functions.With this background, let's rewrite your program in a slightly more readable form:
push %rbp
Move the stack pointer to the stack itself (so we can clean up after all of our junk memory)mov %rsp, %rbp
Resize the stack to0
, Preventing themain()
from accidentally reading junk from other functionsmovl $0x2a, -0x4(%rbp)
Move42
to the first slot in the stack (note: Since an int is 4 bytes big, this is actually the -4th space!)MOV $0x0, %eax
Move0
to the result register (EAX
)POP %RBP
Clean Up after our mess by restoring the old stack pointer. This means that, even though we reset the size of the stack, the program above us will still have all of their memory intact. Remember--We did this to preventmain()
from accessing other function's memory. Great!RETQ
Return and say goodbye ;(If you wanted to retrieve your
42
, you would need to change your code to sayreturn 42
, which would means the compiler would place42
inEAX
, and it would get passed up to your friends above :)