iOS Hacker Xcode玩转arm64汇编基础

已经熟悉了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下写如下代码

#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, char * 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开头的鬼东西,为了看着方便可以删掉。

_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                 		;将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:

这是在真机运行的汇编代码和上面是一样的。

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的过程

	.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]
	mov    x0, x8
        mov    x1, x9         ;到这我们发现,函数参数1-6依次存放到w0-w5,或者说是x1-x5,这和32位是有很大区别的。
  	bl     0x1000d09f0    ;调用funcAdd 

main函数真机运行的汇编代码

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值