了解Xcode中的x86-64汇编代码

时间:2018-02-17 11:49:37

标签: ios xcode x86-64

我没有很多使用汇编或x86-64的经验,而且在调试特定于iOS版本的错误时,我无法理解Xcode提供的汇编代码:

0x108f5607a <+18>:  movq   0x3fe98f(%rip), %rsi      ; "intrinsicContentSize"
0x108f56081 <+25>:  movq   0x47c158(%rip), %r12      ; (void *)0x000000010b4aa800: objc_msgSend
0x108f56088 <+32>:  callq  *%r12
0x108f5608b <+35>:  movsd  %xmm0, -0x30(%rbp)
0x108f56090 <+40>:  movsd  %xmm1, -0x28(%rbp)
0x108f56095 <+45>:  movq   0x426ea4(%rip), %rsi      ; "_contentHuggingPriorities"
0x108f5609c <+52>:  movq   %rbx, %rdi
0x108f5609f <+55>:  callq  *%r12
0x108f560a2 <+58>:  movsd  %xmm0, -0x40(%rbp)
0x108f560a7 <+63>:  movsd  %xmm1, -0x38(%rbp)
0x108f560ac <+68>:  movq   0x426e9d(%rip), %rsi      ; "_contentCompressionResistancePriorities"
0x108f560b3 <+75>:  movq   %rbx, %rdi
0x108f560b6 <+78>:  callq  *%r12
0x108f560b9 <+81>:  movsd  %xmm0, -0x50(%rbp)
0x108f560be <+86>:  movsd  %xmm1, -0x48(%rbp)

感谢汇编代码注释,我猜可以发送3条消息:

  • [obj intrinsicContentSize]
  • [obj _contentHuggingPriorities]
  • [obj _contentCompressionResistance]

但我不明白movsd指令的用途。这是将上述方法调用的返回值复制到寄存器中以便在当前函数中使用吗?如果是,那么假设调用intrinsicContentSize_contentHuggingPriorities的结果被_contentCompressionResistance的结果覆盖是否正确?

1 个答案:

答案 0 :(得分:2)

  

这是否将上述方法的返回值调用复制到寄存器以便在当前函数中使用?

不,相反。 movsd %xmm0, -0x40(%rbp)是商店 xmm0到堆栈上的本地商店。在AT&amp; T语法中,目的地是最后的。 (操作数列表与英特尔语法相反。如果您更熟悉英特尔语法,请将调试器设置为以英特尔语法显示反汇编。)

在此代码中:r12包含一个指向objc_msgSend的函数指针,并使用它进行三次调用。您的反汇编程序有用地为使用RIP相对寻址模式访问的静态位置提供了符号名称。

x86-64 System V调用约定的相关部分:

  • RDI和RSI中的整数args,按此顺序排列。 Arg传递寄存器被调用破坏。 (只有2个参数传递给此函数,因此不使用RDX,RCX,R8,R9)。
  • RBX是调用保留的,并且此代码使用它来重新初始化第一个arg-passing寄存器(RDI),所有三个调用具有相同的值。 (假设在第一个之前RBX = RDI;你没有表明)。
  • 在%xmm0和%xmm1中返回两个FP返回值或结构。
  • 所有xmm / ymm / zmm寄存器都是call-clobbered,因此FP值必须跨函数调用溢出,而不是简单地复制到调用保留寄存器(因为没有任何内容)。