iOS汇编精讲(上篇)

本文是作者学习汇编语言的笔记,重点介绍了ARM64架构下的汇编基础,包括汇编语言概念、寄存器、Hello World示例、函数调用、Call Stack和栈回溯。通过实例解析了汇编代码如何操作内存和CPU,特别强调了在iOS开发中理解汇编对调试和逆向工程的价值。
摘要由CSDN通过智能技术生成

前言

日常的应用开发中,主要用的语言是Objective(Swift),一些特殊场景下,可能还会用到C/C++,JavaScript,Shell,Python等。

那么,一个iOS开发者为什么要了解汇编这么底层的语言呢?

因为看得懂汇编能够提高的代码调试和逆向能力。

本文是作者学习汇编过程中整理的笔记,分为上下两篇:上篇主要是一些基础准备,下篇介绍Objective C汇编和一些逆向的Demo。

命令行

Objective C源文件(.m)的编译器是Clang + LLVM,Swift源文件的编译器是swift + LLVM。

所以借助clang命令,我们可以查看一个.c或者.m源文件的汇编结果

clang -S Demo.m

这是是x86架构的汇编,对于ARM64我们可以借助xcrun

xcrun --sdk iphoneos clang -S -arch arm64 Demo.m

本文所有的汇编都是基于ARM64架构CPU的

汇编是什么?

汇编语言是一种低级编程语言,不同于Objective C这类高级语言,汇编语言是直接操作硬件(CPU,寄存器,内存等)的。

汇编语言仍然不是最低级的语言,CPU不能直接执行,需要通过汇编器转换成机器语言(0101)才能执行。

汇编语言由汇编指令组成,每一个汇编指令都是直接操作CPU去进行一系列操作。一个典型的汇编语句:

//把整数0存储到寄存器x0
mov x0, #0

寄存器

ARM的全称是Advanced RISC Machine,翻译过来是高级精简指令集机器。

iOS设备CPU架构都是基于ARM的,比如你多少都听过这样的名词:arm64,arm7…它们指的都是CPU指令集。iPhone 5s及以后的iOS设备的CPU都是ARM 64架构的。

ARM64常见的的通用寄存器31个64bit,命名为x0-x30,作用:

寄存器 特殊用途 作用
SP Stack Pointer
x30 LR Link Register
x29 FP Frame Pointer
x19…x28 Callee-saved registers
x18 平台保留寄存器,应用不可以使用。
x17 IP1 The second intra-procedure-call temporary register (can be used by call veneers and PLT code); at other times may be used as a temporary register.
x16 IP0 The first intra-procedure-call scratch register (can be used by call veneers and PLT code); at other times may be used as a temporary register.
x9…r15 Temporary registers
x8 间接返回值寄存器,在一些特殊情况下,函数的返回值是通过x8返回的。
x0…x7 用来参数传递给子程序或者从函数中返回值,也可以用来存储中间值

x系列寄存器是64位的,只用低32bit的时候,称做w0~w30

  • SP(Stack Pointer), 可以把栈理解为存储数据的容器,而Stack Pointer告诉你这个容器有多高,你可以通过移动Stack Pointer来增加/减少你的容器容量。
  • LR(Link Register,x30), 在子程序调用的时候保存下一个要执行指令的内存地址。
  • FP(Frame Pointer,x29), 保存函数栈的基地址。

除此之外,还有几个特殊的寄存器

  • PC寄存器保存下一条将要执行的指令的地址,正常情况下PC指令加1,顺序执行下一跳指令,PC按条件执行指令(比如依次执行指令1,指令5,指令3),是条件分支(比如if/while)的理论基础。
  • FLAGS程序状态寄存器,保存若干flags,数据处理的指令会修改这些状态,条件分支指令会读取flag,决定跳转。
  • XZR,和WZR 代表零寄存器

浮点数

由于浮点数运算的特殊性,arm 64还有31个浮点数寄存器q0~q31,长度不同称谓也不同,b,h,s,d,q,分别代表byte(8位),half(16位),single(32位),double(64位),quad(128位)。

Hello world

和任何教程一样, 先看看汇编最简单的汇编代码。新建一个helloworld.c:

#include <stdio.h>

int main()
{
    printf("hello, world\n");
    return 0;
}

然后,生成汇编文件:


                
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值