如何在64位macOS应用程序

时间:2016-12-06 22:35:33

标签: objective-c assembly x86 x86-64

所以我正在调试一个问题,并试图弄清楚这是怎么发生的。

以下是obj-c运行时中方法的程序集,称为objc_msgsend()

libobjc.A.dylib`objc_msgSend:
    0x7fff9084a0c0 <+0>:   testq  %rdi, %rdi
    0x7fff9084a0c3 <+3>:   je     0x7fff9084a140            ; <+128>
    0x7fff9084a0c6 <+6>:   testb  $0x1, %dil
    0x7fff9084a0ca <+10>:  jne    0x7fff9084a14b            ; <+139>
    0x7fff9084a0cd <+13>:  movabsq $0x7ffffffffff8, %r11
    0x7fff9084a0d7 <+23>:  andq   (%rdi), %r11
    0x7fff9084a0da <+26>:  movq   %rsi, %r10
    0x7fff9084a0dd <+29>:  andl   0x18(%r11), %r10d

我正在使用Xcode的lldb来查看寄存器和地址。

这是我得到的有趣输出,当我第一次检查偏移+0处的寄存器时(预期):

(lldb) register read
r11 = 0x00007fff74a940f0  (void *)0x00007fff74a94118: NSObject

偏移+13(预期)之后:

(lldb) register read
r11 = 0x00007ffffffffff8

偏移+23后(不期望):

(lldb) register read
r11 = 0x0000000100761138  (void *)0x0000000100761160: GTMOAuth2WindowController

然后如果我po寄存器此处:

(lldb) po $rdi
<GTMOAuth2WindowController: 0x6100001c2850>

(lldb) po &$rdi
0x000000010bc2b3b8

(lldb) po $r11
GTMOAuth2WindowController

(lldb) po &$r11
0x000000010bc2b3b8

所以这就是我迷失的地方;在偏移+23之后,当register read时,该地址是什么? 0x0000000100761138。我希望它有0x6100001c2850,来自+23

的解引用对象的位置

如果我po $r11它打印出类名(这是预期的,因为我们正在查看isa属性),如果我在内存中打印指针的位置,它就不会t匹配register read中的地址,它与%rdi(预期)的地址匹配。

1 个答案:

答案 0 :(得分:2)

%r11之后的<+23>中的地址0x0000000100761138是代表您的GTMOAuth2WindowController类的类对象的地址。

在编译时定义一个类(使用@interface@implementation)时,运行时会有一个表示类的特殊对象。事实上,它被称为“类对象”,并且就像您创建的所有对象一样是一个真实对象。这意味着类对象本身可以响应消息。在po %r11之后说<+23>时,调试器将description消息发送到类对象。类对象的description方法将类的名称返回为NSString,因此调试器打印了类的名称。

You can learn more about class objects here。该页面上的图片链接已在Chrome中中断,但您可以点击它以查看pdf。