【问题标题】:Studying a simplistic code disassembly output and memory map研究一个简单的代码反汇编输出和内存映射
【发布时间】:2014-10-04 15:39:52
【问题描述】:

有人可以向我解释一下下面发生了什么吗? 问题:

  • 为什么变量 i 不留在寄存器中?
  • 为什么寄存器 rbp 包含内存缓存行的地址而不是 i 的地址(即 4 个字节)?
  • 这是什么意思? 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 编译的。

【问题讨论】:

  • 现金是什么意思?缓存?
  • 缓存不能单独寻址。所以我不确定你关于缓存的问题是什么意思。
  • 我的意思是,我给 i 分配了 5。 5不应该在缓存中而不是映射到内存吗?
  • 我认为您需要了解缓存的工作原理:en.wikipedia.org/wiki/CPU_cache
  • 啊对不起yyyy我会更新我的问题,我的意思是注册!!!

标签: c++ memory assembly


【解决方案1】:
  • 为什么变量 i 不留在寄存器中?

因为你的编译器不喜欢它。它决定将变量i 放在堆栈上。

  • 为什么寄存器 rbp 包含内存缓存行的地址而不是 i 的地址(即 4 个字节)?

rbp 不包含内存缓存的地址rbpBase Pointer,指向栈底。 -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 是什么意思?

有两种常见的汇编语法

  1. AT&T,一团糟
  2. “常规”英特尔语法

很遗憾,您的代码在 AT&T 中。 % 是在 AT&T 语法中引用变量的方式。 -0x4 是数字 -4 的十六进制表示(参见上面的答案)。

http://en.wikipedia.org/wiki/X86_assembly_language#Syntax

【讨论】:

    【解决方案2】:
    • 您的意思是“不在注册表中”吗?因为你的程序不是用高优化设置编译的(但是如果你用高优化值编译你的整个过程将是空的,因为它不“做任何事情”(没有副作用)。包含你的变量的地址肯定是当 CPU 执行这些指令时被带入内存缓存

      • register rbp 包含函数堆栈框架的基址,它是分配本地自动变量的地方,这是由您的语言的调用约定指定的。

      • 在这种情况下,mov 指令是将立即值移动到内存位置。 % 以寄存器名称开头。由于堆栈通常向下增长,因此局部自动变量的偏移量是相对于框架/堆栈底部的负偏移量。

    【讨论】:

      【解决方案3】:
      • 没有“缓存地址”之类的东西 - 缓存是从程序中抽象出来的,只有 CPU 和操作系统知道缓存以及如何将内存地址转换为“缓存地址”

      • 变量 i 在堆栈上分配。 rbp 是帧的“基指针”,它指向正在堆栈上执行的当前函数的帧。所以-0x4(%rbp) 表示在寄存器 rbp 的偏移量 4(向后 - 稍后返回该点)中,变量 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, 在思考关于记忆的“大局”时,它真的帮助了我很多。

      【讨论】:

        【解决方案4】:
        • 为什么变量 i 不留在寄存器中?

        这是编译器的决定。在过去,人们会使用关键字register 来提示编译器该变量被频繁使用,以便编译器可以使用寄存器来存储该字段而不是堆栈条目。但现在不建议这样做,因为现在编译器非常聪明,并且通常会比我们优化得更好。

        • 为什么寄存器 rbp 包含内存高速缓存行的地址和 不是 i 的地址(即 4 个字节)?

        进入函数时,局部变量将被压入堆栈。在此之后 rbp 将被设置为堆栈指针 rsp 的值。由于 rsp 指向下一个空闲空间,rbp 也是如此,所以你需要 -4 来获取最后一个压入堆栈的变量的地址,在本例中为 i

        • 这是什么意思? movl $0x5,-0x4(%rbp); % 和 the 负 0x4 是什么意思?

        将值 0x5 放入地址 rbp-4。

        【讨论】:

          猜你喜欢
          • 2010-09-11
          • 1970-01-01
          • 2020-05-09
          • 2015-02-25
          • 1970-01-01
          • 2013-04-18
          • 1970-01-01
          • 1970-01-01
          • 2011-02-05
          相关资源
          最近更新 更多