Monday, January 12, 2009

How-to do ARM GCC Inline Assembler for iPhone

The following code demonstrates an example to write Inline Assembler in llvm-gcc for iPhone ARM

arithmetic_shift_right.c Select all

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]) {
int i = atoi(argv[1]);
asm volatile ("mov %0, %1, ASR #1" : "=r"(i) : "r"(i));
printf("arithmetic_shift_right is %d\n", i);
exit(0);
}


The general format (ref) is
asm volatile (assembler instructions : output operands (optional) : input operands (optional) : clobbered registers (optional) );

e.g.
asm volatile ("mul %0, %1, %2" : "=r" (result) : "r" (number1) , "r" (number2));


This version is for Assembler Macro

arithmetic_shift_right.c Select all

#include <stdio.h>
#include <stdlib.h>

inline int arithmetic_shift_right(int a) {
int y;
__asm__("mov %0, %1, ASR #1" : "=r" (y) : "r" (a));
// Register R0 will become the value of register R1 shifted to the right by 1 bit, with the sign maintained.
return y;
}

int main(int argc, char *argv[]) {
int i = atoi(argv[1]);
printf("arithmetic_shift_right %d is %d\n", i, arithmetic_shift_right(i));
exit(0);
}



Below is the otool output for Assembler Macro
otool -tV Select all

_arithmetic_shift_right:
00001eb4 e92d4080 stmdb sp!, {r7, lr}
00001eb8 e28d7000 add r7, sp, #0 ; 0x0
00001ebc e24dd008 sub sp, sp, #8 ; 0x8
00001ec0 e58d0000 str r0, [sp]
00001ec4 e59d3000 ldr r3, [sp]
00001ec8 e1a030c3 mov r3, r3, asr #1       @@ arithmetic shift right
00001ecc e58d3004 str r3, [sp, #4]
00001ed0 e59d3004 ldr r3, [sp, #4]
00001ed4 e1a00003 mov r0, r3
00001ed8 e247d000 sub sp, r7, #0 ; 0x0
00001edc e8bd8080 ldmia sp!, {r7, pc}


Below is the otool output for Assembler Macro (after full optimzation -O2)
otool -tV Select all

_arithmetic_shift_right:
00001f04 e1a000c0 mov r0, r0, asr #1
00001f08 e12fff1e bx lr




Assembler Macro for more than one assembler instruction
arithmetic shift right then perform 16 bit binary multiplication

Assembler Macros Select all

__asm__("mov %0, %1, ASR #1\n\t"
"mul %0, %0, %1"
: "=r" (y) : "r" (a));





2 comments:

Ole Gammelgaard said...

In what cases would this me useful? To optimize for speed or to perform operations that Apple don't allow?

javacom said...

I prefer to use it after the reverse engineering of iPhone code.