I want to know how objective C runtime handle arguments when I call a objective C method like
[NSString stringWithFomat:@"%@, %@", @"Hello", @"World"]
There are three arguments for this objective C call, how does it work compared to typical way on a ARM system. I have known register r0, r1, r2, r3 will hold first 4 arguments, how about there are additional arguments? How does it put them on a stack and pop them later?
Calling conventions specify how arguments are passed to a function, how return values are passed back out of a function, how the function is called, and how the function manages the stack and its stack frame. In short, the calling convention specifies how a function call in C or C++ is converted into assembly language.
The argument and “temporary” registers are not callee saved, and must be saved by the calling function if their values should be preserved. This means that within a function we can uses these registers freely, without the need to save/restore their values.
__cdecl is the default calling convention for C and C++ programs. Because the stack is cleaned up by the caller, it can do vararg functions. The __cdecl calling convention creates larger executables than __stdcall, because it requires each function call to include stack cleanup code.
For example, which register holds 13 in main's call to printf? a0–a7 and fa0-fa7contains function arguments.
For functions that returns a simple type:
r0 = self (NSString)
r1 = _cmd (@selector(stringWithFormat:))
r2 = 1st argument (@"%@, %@")
r3 = 2nd argument (@"Hello")
then the rest is placed on the stack:
[sp,#0] = 3rd argument (@"World")
[sp,#4] = 4th argument (does not exist in your example)
...
Of course, "argument" here means a 4-byte object. If the argument has >4 bytes then it will be split out, e.g.
-[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
The returned value (up to 16 bytes) will be placed in r0, r1, r2, r3.
For functions that returns a struct: r0
is used to store the pointer of the return value.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With