在汇编器AT& t上下文中:Movl在指定的行中有什么作用?

发布于 2025-01-23 11:01:30 字数 451 浏览 2 评论 0原文

我在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:
enter image description here

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

清泪尽 2025-01-30 11:01:30

c中的每个变量要么在内存中获得设置位置(称为 a register 。实际上,编译器通常会在这两个绩效位置之间移动变量。

movl将32位编号(您的int!)从一个寄存器移至另一寄存不使用寄存器的那一部分。

按下pop从堆栈中添加并删除项目。 C编译器通常使用它来保存寄存器。作为调用main()的函数,您不知道它的作用,以及在所有内存main()使用后如何清理,这就是为什么它是<代码> main()有责任自行清理,使程序完全按照其开始。 (当然,除了操作的结果外)

eax是一个普通寄存器,通常用于功能结果。

使用此背景,让我们以更可读的形式重写您的程序:

  1. 按%RBP 移动 堆栈指针堆栈本身(因此,我们可以在所有之后清理所有垃圾存储器)
  2. MOV%RSP,%RBP resize 0防止 main( )其他 functions functions
  3. movl $ 0x2a,-0x4(%rbp) move 42 到堆栈中的第一个插槽(注意:由于int是4个字节大,这实际上是-4个空间!)
  4. 等待 - 我们从未真正调整堆栈的大小来告诉其他程序我们的特殊号码在那里。这是因为编译器对其进行了优化,因为它看到我们要在几个说明中重置时正在增加大小。
    • 谢谢彼得·科德斯(Peter Cordes),提醒我“ nofollow noreferrer”>红色区域存在!这是堆栈内部内存的特殊区域,不需要在写入之前扩展堆栈。在此程序的情况下,这可能是正在发生的事情。
  5. mov $ 0x0,%eax move 0到结果寄存器(eax
  6. pop%RBP < /code> 清理在我们混乱之后,通过还原旧的堆栈指针。这意味着,即使我们重置堆栈的大小,我们上方的程序仍将完好无损。请记住 - 我们这样做是为了防止main()访问其他函数的内存。伟大的!
  7. 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, while MOV moves an entire register, even if your program doesn't use that part of the register.

PUSH and POP add and remove items from the stack. It's often used by the C compiler to save registers. As a function calling main(), you have no idea what it does, and how to clean up after all the memory main() uses, which is why it is main()'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:

  1. push %rbp Move the stack pointer to the stack itself (so we can clean up after all of our junk memory)
  2. mov %rsp, %rbp Resize the stack to 0, Preventing the main() from accidentally reading junk from other functions
  3. movl $0x2a, -0x4(%rbp) Move 42 to the first slot in the stack (note: Since an int is 4 bytes big, this is actually the -4th space!)
  4. Wait-- We never actually resized the stack to tell other programs that our special number is there. This is because the compiler optimized it away, as it saw that we were increasing the size when we were going to reset it in a few instructions anyways.
    • Thank you Peter Cordes, for reminding me the Red Zone exists! This is a special area of memory inside of the stack which does not require the stack to be expanded before writing to it. In the case of this program, this is likely what is happening.
  5. MOV $0x0, %eax Move 0 to the result register (EAX)
  6. 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 prevent main() from accessing other function's memory. Great!
  7. RETQ Return and say goodbye ;(

If you wanted to retrieve your 42, you would need to change your code to say return 42, which would means the compiler would place 42 in EAX, and it would get passed up to your friends above :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文