iOS Assembly Tutorial: Understanding ARM

Learn how to read assembly in iOS – a useful skill when debugging your code or diagnosing why a crash has occurred. By Matt Galloway.

Leave a rating/review
Save for later
Share
You are currently viewing page 4 of 4 of this article. Click here to view the first page.

Reverse Engineer, You Can Now

With just that little knowledge of ARM assembly, you should be able to get a feel for why something is breaking, crashing or not working correctly. Why might you want to drop down to looking at the assembly? Because you can interrogate in much more detail and see precisely the steps that led up to a bug.

interrogation

Sometimes, you don’t have the source to look at – for example, if you’re experiencing a crash inside a third-party library or a system framework. Being able to investigate via the assembly can lead to finding the problem quickly. The iOS SDK ships with all frameworks in the following directory:

<Path_to_Xcode>/Contents/Developer/Platforms/iPhoneOS.platform/Developer/ SDKs/iPhoneOS6.1.sdk/System/Library/Frameworks

To investigate these libraries, I recommend purchasing HopperApp, which will disassemble a binary so you can take a look at it. There’s nothing wrong with doing this! For example, opening up UIKit, you can take a look at what each method does. This is what it looks like:

05 - HopperApp 1

This is the assembly for the -[UINavigationController shouldAutorotateToInterfaceOrientation] method. With your newfound ARM assembly knowledge, you should be able to work out what’s going on here.

First a selector reference is being loaded into r1, ready for the call to objc_msgSend. Then notice that no other registers are touched, so the self pointer passed to objc_msgSend in r0 is the same as the one passed into shouldAutorotateToInterfaceOrientation.

Also, you know that the method being called takes one parameter, as there is one colon in its name. Since r2 is left untouched, the first parameter passed into shouldAutorotateToInterfaceOrientation is what gets passed.

Finally, after the method call, r0 is untouched, so the value that gets returned from this method is the return value of the method call.

So you can deduce that this method is performing the following:

- (BOOL)shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation)interfaceOrientation {
    return [self _doesTopViewControllerSupportInterfaceOrientation:interfaceOrientation];
}

Wow! That was easy! Often the logic in a method is a bit more complicated than that, but usually you can piece things together and quickly work out what a certain portion of code is doing.

Where to Go from Here?

This iOS assembly tutorial has given you some insight into the core concepts of ARM, as used in code running on iOS devices. You have learned about calling conventions for C and Objective-C.

ARMed with this knowledge (pun intended!), you have the tools to start understanding all those random codes you see when your app crashes deep in a system library. Or maybe you just want to drop down to the assembly for your own methods so you can see exactly what is going on.

If you’re interested in diving deeper into ARM, I recommend purchasing a Raspberry Pi. These little devices have an ARM processor very similar to those found in iOS devices and there are many tutorials out there that will teach you how to program them.

Another thing to look into is NEON. This is an additional set of instructions available in all processors from the iPhone 3GS onward. It provides SIMD (Single Instruction Multiple Data) instructions that allow you to process data extremely efficiently. Applications for these instructions are things like manipulating images. If you need to do this efficiently, then it could be beneficial to learn how to write NEON instructions directly, using inline assembly. This is extremely advanced, though!

This should be enough to keep you busy for awhile. Let us know about your ARM adventures in the forums.