已经熟悉了x86汇编,所以其他的理论就不多记了,主要是记录以下这些。
iphon5s以上都是arm64的设备
armv6 设备:iPhone, iPhone2, iPhone3G, 第一代、第二代 iPod Touch
armv7 设备:iPhone3GS, iPhone4, iPhone4S
iPad, iPad2, iPad3(The New iPad), iPad mini
iPod Touch 3G, iPod Touch4
armv7s设备:iPhone5, iPhone5C, iPad4(iPad with Retina Display)
arm64 设备:iPhone5S, iPad Air, iPad mini2(iPad mini with Retina Display)
最常用汇编指令
str 将数据从寄存器中读取存放到内存
ldr 将内存中的数据读取放到寄存器
bl 跳转
32位寄存器
R0-R3 //函数的前4个参数放在R0-R3中,其他的参数放到栈中,返回值在R0
R7
R9
R13 //SP寄存器
R14 //LR寄存器,保存函数返回地址
R15 //PC寄存器
32位的寄存器容量是8位,64位寄存器的容量16位的,数量也更多一些,x1,x2,x3...
---------------------------------------------------------------------
以下是64位的arm汇编的一个实例,理解arm汇编的函数调用的过程。
打开Xcode,新建ios工程,在main.m下写如下代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
#import <UIKit/UIKit.h> #import "AppDelegate.h" int funcAdd(a,b,c,d,e,f) { int g=a+b+c+d+e+f; return g; } int main(int argc, charchar * argv[]) { funcAdd(1, 2, 3, 4, 5, 6); @autoreleasepool { return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); } } |
在Xcode菜单栏选择Product=>Perform Action => Assemble main.m, 注意选择在真机编译才能生成arm汇编,在模拟器是x86的。
显示代码有很多.loc开头的鬼东西,为了看着方便可以删掉。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
_funcAdd: ; @funcAdd Lfunc_begin0: .loc 1 13 0 ; /Users/exchen/Desktop/armasm/armasm/main.m:13:0 .cfi_startproc ; BB#0: sub sp, sp, #32 ; =32 Ltmp1: .cfi_def_cfa_offset 32 str w0, [sp, #28] ;将w0寄存器的值放入sp+28,第1个参数a str w1, [sp, #24] ;将w1寄存器的值放入sp+24,第2个参数b str w2, [sp, #20] ;将w2寄存器的值放入sp+20,第3个参数c str w3, [sp, #16] ;将w3寄存器的值放入sp+16,第4个参数d str w4, [sp, #12] ;将w4寄存器的值放入sp+12,第5个参数e str w5, [sp, #8] ;将w5寄存器的值放入sp+8, 第6个参数f .loc 1 14 11 prologue_end ; /Users/boot/Desktop/armasm/armasm/main.m:14:11 Ltmp2: ldr w0, [sp, #28] ;将第1个参数a放入w0寄存器 ldr w1, [sp, #24] ;将第2个参数b放入w1寄存器 add w0, w0, w1 ;将w0和w1的值相加并存入w0寄存器 ldr w1, [sp, #20] ;将第3个参数e放入w1寄存器 add w0, w0, w1 <span style="white-space:pre"> </span>;将w0和w1的值相加并存入w0寄存器 ldr w1, [sp, #16] ;将第4个参数d放入w1寄存器 add w0, w0, w1 ;将w0和w1的值相加并存入w0寄存器 ldr w1, [sp, #12] ;将第5个参数e放入w1寄存器 add w0, w0, w1 ;将w0和w1的值相加并存入w0寄存器 ldr w1, [sp, #8] ;将最后一个参数f放入w1寄存器 add w0, w0, w1 ;将w0和w1的值相加并存入w0寄存器 str w0, [sp, #4] ldr w0, [sp, #4] add sp, sp, #32 ; =32 ret Ltmp3: Lfunc_end0: |
这是在真机运行的汇编代码和上面是一样的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
armasm`funcAdd: 0x1000389f0 <+0>: sub sp, sp, #32 0x1000389f4 <+4>: str w0, [sp, #28] 0x1000389f8 <+8>: str w1, [sp, #24] 0x1000389fc <+12>: str w2, [sp, #20] 0x100038a00 <+16>: str w3, [sp, #16] 0x100038a04 <+20>: str w4, [sp, #12] 0x100038a08 <+24>: str w5, [sp, #8] -> 0x100038a0c <+28>: ldr w0, [sp, #28] 0x100038a10 <+32>: ldr w1, [sp, #24] 0x100038a14 <+36>: add w0, w0, w1 0x100038a18 <+40>: ldr w1, [sp, #20] 0x100038a1c <+44>: add w0, w0, w1 0x100038a20 <+48>: ldr w1, [sp, #16] 0x100038a24 <+52>: add w0, w0, w1 0x100038a28 <+56>: ldr w1, [sp, #12] 0x100038a2c <+60>: add w0, w0, w1 0x100038a30 <+64>: ldr w1, [sp, #8] 0x100038a34 <+68>: add w0, w0, w1 0x100038a38 <+72>: str w0, [sp, #4] 0x100038a3c <+76>: ldr w0, [sp, #4] 0x100038a40 <+80>: add sp, sp, #32 0x100038a44 <+84>: ret |
main函数里调用funcAdd的过程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
.globl _main .align 2 _main: ; @main Lfunc_begin1: .loc 1 17 0 is_stmt 1 ; /Users/exchen/Desktop/armasm/armasm/main.m:17:0 .cfi_startproc ; BB#0: stp x29, x30, [sp, #-16]! mov x29, sp sub sp, sp, #64 ; =64 Ltmp4: .cfi_def_cfa w29, 16 Ltmp5: .cfi_offset w30, -8 Ltmp6: .cfi_offset w29, -16 orr w8, wzr, #0x1 ;和mov w8,#0x1是一样的 orr w9, wzr, #0x2 ;同上 orr w2, wzr, #0x3 orr w3, wzr, #0x4 movz w4, #0x5 orr w5, wzr, #0x6 stur wzr, [x29, #-4] stur w0, [x29, #-8] stur x1, [x29, #-16] <span style="white-space:pre"> </span>mov x0, x8 mov x1, x9 ;到这我们发现,函数参数1-6依次存放到w0-w5,或者说是x1-x5,这和32位是有很大区别的。 bl 0x1000d09f0 ;调用funcAdd |
main函数真机运行的汇编代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
armasm`main: 0x1000d0a48 <+0>: stp x29, x30, [sp, #-16]! 0x1000d0a4c <+4>: mov x29, sp 0x1000d0a50 <+8>: sub sp, sp, #64 0x1000d0a54 <+12>: orr w8, wzr, #0x1 0x1000d0a58 <+16>: orr w9, wzr, #0x2 0x1000d0a5c <+20>: orr w2, wzr, #0x3 0x1000d0a60 <+24>: orr w3, wzr, #0x4 0x1000d0a64 <+28>: movz w4, #0x5 0x1000d0a68 <+32>: orr w5, wzr, #0x6 0x1000d0a6c <+36>: stur wzr, [x29, #-4] 0x1000d0a70 <+40>: stur w0, [x29, #-8] 0x1000d0a74 <+44>: stur x1, [x29, #-16] -> 0x1000d0a78 <+48>: mov x0, x8 0x1000d0a7c <+52>: mov x1, x9 0x1000d0a80 <+56>: bl 0x1000d09f0 ; funcAdd at main.m:13 |