【问题标题】:Question about Objective C calling convention and argument passing on ARM关于 ARM 上的 Objective C 调用约定和参数传递的问题
【发布时间】:2023-03-28 15:48:01
【问题描述】:

我想知道当我调用像这样的目标 C 方法时,目标 C 运行时如何处理参数

[NSString stringWithFomat:@"%@, %@", @"Hello", @"World"]

这个目标 C 调用有三个参数,与 ARM 系统上的典型方式相比,它是如何工作的。我知道寄存器 r0, r1, r2, r3 将保存前 4 个参数,那么还有其他参数怎么样?它如何将它们放入堆栈并稍后将它们弹出?

【问题讨论】:

    标签: iphone compiler-construction assembly arm calling-convention


    【解决方案1】:

    对于返回简单类型的函数:

    r0 = self (NSString)
    r1 = _cmd (@selector(stringWithFormat:))
    r2 = 1st argument (@"%@, %@")
    r3 = 2nd argument (@"Hello")
    

    然后将其余的放在堆栈上:

    [sp,#0] = 3rd argument (@"World")
    [sp,#4] = 4th argument (does not exist in your example)
    ...
    

    当然,这里的“参数”是指一个 4 字节的对象。如果参数有 >4 个字节,那么它将被拆分,例如

    -[UIView initWithFrame:rect];
    
    r0 = self
    r1 = _cmd
    r2 = rect.origin.x
    r3 = rect.origin.y
    [sp,#0] = rect.size.width
    [sp,#4] = rect.size.height
    

    返回的值(最多 16 个字节)将放在 r0, r1, r2, r3 中。


    对于返回结构体的函数:r0 用于存储返回值的指针。

    NSRange retval = [self rangeOfString:string options:options range:range]
    
    r0 = &retval (of type NSRange*)
    r1 = self
    r2 = _cmd (@selector(rangeOfString:options:range:))
    r3 = string
    [sp,#0] = options
    [sp,#4] = range.location
    [sp,#8] = range.length
    

    【讨论】:

    • 这正是我需要知道的,谢谢提醒!
    • 嗯,我知道这是一个愚蠢的问题,但是......你如何访问寄存器?
    猜你喜欢
    • 2016-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-17
    • 1970-01-01
    • 1970-01-01
    • 2013-08-07
    • 1970-01-01
    相关资源
    最近更新 更多