fruitfly

a technical blog

ARM Assembler for iOS: Part 1 – Environment Setup

with 15 comments

A few weeks ago I came into the need of optimizing some OpenGL code for iOS. There was alot of matrix- and vector-calculations going on that could greatly be improved by taking advantage of the NEON coprocessor found in every of the newer iPhone and iPad versions. It is a vector-based processor also allowing single-precission float-point calculations. Taking advantage of this processor for OpenGL applications can make a signification difference as you often do vector-based floating-point calculations. Nicely, there already exist a library that provides all that is needed regarding vector- and matrix-opertions and leverages the NEON chip by implementing the main functionality directly in assembly code (you are not able to directly access that coprocessor from your C-code). My only problem: I always like to understand what I am doing and would even sometimes rather re-implement some library myself then blindly reusing something I don’t understand the inner-workings of. Not sure if this is a good quality or a bad one…

This led me to the goal for this series of posts: Learn assembly for the ARM chip, which is found in all of the iOS-powered devices by Apple (and also in most other phones that play in the same league as the iPhone). I will try to write down my experience and the learned stuff within this series to help others getting started as well. For this, I will heavily rely on external resources like documentations, blog-posts and tutorials. This “diary” will function as the glue that holds everything together and makes me stick with my set goal to learn ARM assembly.

In this parts of the series we will focus on setting up the environment and make sure that our tool-chain is working. Namely, we will do the following:

  • Install the GNU ARM Assembler toolchain
  • Build a first Hello-World C-application that we will compile, run and debug with the installed toolchain

Lets get started!

Installing the GNU ARM toolchain

As the iOS applications compiled for the iPhone Simulator are translated to normal x68 code (the simulator does not simulate an ARM chip) we cannot just write assembly code in your iOS project and run it in the simulator. For sure, we don’t want to connect an iOS device for our early fiddling with the ARM chip. Thus we will install the GNU ARM Assembler tool-chain which is free and comes with a simulator that allows us to run the developed code without a real device.

Go to the GNU ARM webpage and download the binary for your architecture. As I am focusing on Apple mobile devices, i assume you will download the toolchain for Mac OSX.

After unpacking and installing the download, you should have the following tools installed, that you are able to call from you command-line shell

  • arm-elf-gcc The gcc compiler to build executables
  • arm-elf-run To run executables
  • arm-elf-gdb The debugger to debug built executables
  • arm-elf-objdump To disassemble/read out sections of the library

As you might notice, these are all the standard binutils you already know. They only support (and compile for) the ARM architecture, but if you are familiar with gcc, gdb, etc, you should have no big problems with these tools.

The only small negative point is that these tools build and run ELF-based executables and not the Mach-O executables known from Mac OSX and iOS. So, you will have to use objdump here, but use otool for example on your iOS executables. But it is not really justified to make such a complaint…

Building a simple Hello-World App for the ARM chip

Lets build a very simple Hello-World app. We will compile, link, run and debug that app with the just installed tools.

Create a helloworld.c file with the following content:

 

#include <stdio.h>

int main(int argc, char *argv[])
{
	char *str = "hello world";
	printf("%s\n", str);

	asm volatile("mov r0,r0");

	return 0;
}

You can see that the file only prints out “hello world” and has a simple stub for adding some assembly-code to playing around with the ARM-specifics. The “mov r0,r0”, is basically a no-op and we don’t worry about it for now.

Perform the following set of calls to build, link and run the executable (named “hw”):

 

arm-elf-gcc -mcpu=arm7 -O2 -g -c helloworld.c  -o helloworld.o
arm-elf-gcc -mcpu=arm7 -o hw helloworld.o -lc
arm-elf-run hw

There should be no problems with these steps and running the “hw” exectuable should actually print “hello world” to the commandline; but I just also want to show you how to start the executable in the debugger:

 

macbook:arm-asm daniel$ arm-elf-gdb
GNU gdb 6.0
Copyright 2003 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "--host=powerpc-apple-darwin6.8 --target=arm-elf".
(gdb) file hw
Reading symbols from hw...done.
(gdb) target sim
Connected to the simulator.
(gdb) load
Loading section .init, size 0x1c vma 0x8000
Loading section .text, size 0x2d74 vma 0x801c
Loading section .fini, size 0x18 vma 0xad90
Loading section .rodata, size 0x18 vma 0xada8
Loading section .data, size 0x8a8 vma 0xaec0
Loading section .eh_frame, size 0x4 vma 0xb768
Loading section .ctors, size 0x8 vma 0xb76c
Loading section .dtors, size 0x8 vma 0xb774
Loading section .jcr, size 0x4 vma 0xb77c
Start address 0x811c
Transfer rate: 111616 bits in <1 sec.
(gdb) run
Starting program: /Users/daniel/tmp/arm-asm/hw
hello world

Program exited normally.
[Switching to process 0]

You see, it requires first to call “file hw”, to load the executable, “target sim”, then “load” and finally “run” to run the executable. All further commands, like setting break-points and stepping through the code is standard gdb and you can look it up in any regular tutorial on this toolchain (you can already do alot with break, stepi, nexti, continue, list and print).

Do you remember the “mov r0,r0” assembly instruction in our code? We can use “arm-elf-objdump -d hw” to actually disassembly the executable and see it listed as a “nop”:

 

macbook:arm-asm daniel$ arm-elf-objdump -d hw | grep -A 12 "<main>:"
00008224 <main>:
    8224:	e1a0c00d 	mov	ip, sp
    8228:	e92dd800 	stmdb	sp!, {fp, ip, lr, pc}
    822c:	e24cb004 	sub	fp, ip, #4	; 0x4
    8230:	e59f000c 	ldr	r0, [pc, #12]	; 8244 <main+0x20>
    8234:	eb00023e 	bl	8b34 <puts>
 8238: e1a00000 nop (mov r0,r0)
    823c:	e3a00000 	mov	r0, #0	; 0x0
    8240:	e91ba800 	ldmdb	fp, {fp, sp, pc}
    8244:	0000ada8 	andeq	sl, r0, r8, lsr #27

00008248 <atexit>:
    8248:	e1a0c00d 	mov	ip, sp

Congratulations! You have successfully installed the tool-chain and are now ready to fiddle around with ARM assembly.

Further Reading

As a homework for the next part of the series, i will assume you have a look at the following really great resources:

The first tutorial was originally written for the Gameboy Advanced, but that should not confuse you. The GBA also uses an ARM7-chip and thus we can transfer almost all of the learned to our iOS devices.

You actually might wamt to play around a little with what you learn in the tutorial. Do you remember the “asm volatile” block in your main-method? You could use it to put some simple assembler code in and just play around. Details on how to pass and return back C-based variables to/from this inline-code, can be found in this very well-written blog-post. I don’t assume you go through it in every detail (we will come back to it later), but it will help you if you want to pass values between C- and assembly-code and not have to worry about call-conventions between C- and assembly-code too much. Actually, this will be the topic in Part 2 or 3 of the series.

Written by 38leinad

April 6, 2011 at 7:34 pm

Posted in arm

Tagged with ,

15 Responses

Subscribe to comments with RSS.

  1. Interesting! I’ll have to keep checking this up, as it looks like I found someone else who likes re-inventing the wheel 🙂 I’ll have to get a few development tools (which got wiped when I installed Snow Leopard a few weeks ago).

    Cheers,

    Ruben

    Ruben Berenguel

    April 6, 2011 at 8:14 pm

  2. My only problem: I always like to understand what I am doing and would even sometimes rather re-implement some library myself then blindly reusing something I don’t understand the inner-workings of. Not sure if this is a good quality or a bad one…

    — I feel you my friend 🙂 and i can assure you its a very good habit. !

    Markus Pfundstein

    February 24, 2012 at 7:30 am

  3. I dont really understand how i would set everything up, to create a build environment in Windows, could you give more detailed instructions?

    Samuel

    May 23, 2012 at 8:59 pm

    • sorry; never installed it on windows. I saw a cygwin installation package for windows. Have a check at that one. but i you are not familiar with unix environments and cygwin, this might be a steep learning curve for you.

      cheers,
      daniel

      38leinad

      May 27, 2012 at 5:09 pm

  4. Hi, I think I did something incorrect:
    Launch of “arm-elf-gcc” failed: the PowerPC architecture is no longer supported.

    any ideas?

    wren

    June 4, 2012 at 7:57 pm

    • i guess you downloaded a version that is only supporting the new intel architecture. Try maybe downloading an older version of the package that still supports PowerPC. As I have an intel-based macbook I never stumbled on this problem. sorry.

      38leinad

      June 4, 2012 at 8:01 pm

  5. I have Mac OS X Version 10.7.5 on a 2GHz Intel Core i7.

    I too received the error message:

    Launch of “arm-elf-gcc” failed: the PowerPC architecture is no longer supported.

    I then attempted to download the GCC-4.1 toolchain source and compile it. This doesn’t work either

    gcc -DHAVE_CONFIG_H -I. -I.././binutils -I. -D_GNU_SOURCE -I. -I.././binutils -I../bfd -I.././binutils/../bfd -I.././binutils/../include -I.././binutils/../intl -I../intl -DLOCALEDIR=”\”/usr/local/share/locale\”” -Dbin_dummy_emulation=bin_vanilla_emulation -W -Wall -Wstrict-prototypes -Wmissing-prototypes -Werror -g -O2 -c strings.c
    cc1: warnings being treated as errors
    strings.c: In function ‘strings_file’:
    strings.c:435: warning: ‘stat64’ is deprecated (declared at /usr/include/sys/stat.h:466)
    make[4]: *** [strings.o] Error 1
    make[3]: *** [all-recursive] Error 1
    make[2]: *** [all] Error 2
    make[1]: *** [all-binutils] Error 2
    make: *** [all] Error 2

    I then tried to compile the source on my ubuntu 12.04 LTS Desktop and this didn’t work either.

    The GNU Arm Files page isn’t date stamped so I have no idea when these files were last made. The README file contains no dates.

    If somebody from ARM reads this, please produce some working .dmg and Debian install packages please, so “the rest of us” mere mortals can enjoy using the ARM Assembler and cross compiler on our Linux and Macs.

    Anon

    November 2, 2012 at 11:48 am

  6. i think the easy way doesnt work anymore.
    seems you need to do it like http://www.ethernut.de/en/documents/cross-toolchain-osx.html
    but im also still about to try it. anyway, you can also directly paste your inline-assembler directly in your objective-c code and directly run it on your ios-device. thats how im doing it actually(using the advices of http://www.ethernut.de/en/documents/arm-inline-asm.html and of course http://gcc.gnu.org/onlinedocs/gcc-4.2.4/gcc/.

    Tim W

    November 26, 2012 at 5:09 pm

  7. Another quick introduction to ARM assembly and reverse engineering: yurichev.com/writings/RE_for_beginners-en.pdf

    timclimber

    August 13, 2013 at 5:20 am

  8. I’m very happy to uncover this page. I need to to thank
    you for ones time just for this wonderful read!! I definitely liked every little bit of it and
    I have you saved as a favorite to see new things on your web site.

    Life quotes

    March 30, 2015 at 3:10 am

  9. Sono state testate 20 donne con età compresa tra 20 e 35
    anni, 10 trattate con pillole Erdic e 10 con pillole
    placebo.

    aumentare il seno

    January 26, 2016 at 7:16 am


Any thoughts?

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: