iOS 底层系统小结
CPU架构体系
x86/x64指令集:64位架构
由于32位特性的长度,要处理大量的信息储存大于4GB会有困难。
在iOS编程时如果要运行在模拟器上,代码生成的机器指令时就需要指定使用i386还是x64指令集,因为目前的mac电脑上基本采用了x86或者x64架构的CPU。
ARM指令集
第一款低功耗成本的RISC微处理器。全称为Advanced RISC Machine。ARM处理器本身是32位设计,但也配备16位指令集。
目前市面上的主流智能手机等移动设备配备的CPU都采用ARM架构。iOS应用真机编译出来的机器指令都是ARM指令,因此需要在编译时指定armv7或者arm64指令集。
Xcode的汇编模式切换
Xcode汇编代码和源代码之间的切换可以通过菜单:Debug -> Debug Workflow -> Always Show Disassembly 来完成。记得要设置有断点并运行到断点处时切换才能看到汇编指令啊!
(X86架构:movq 源 目的;而ARM64架构:mov 目的 源)
系统所有的代码都是由一个个的函数或者说方法组成,即使是类中定义的方法以及Block里面的方法也是如此。在编译时系统将所有定义的函数方法依次编译链接为机器指令并保存到文件的代码段中,一个函数内的机器指令是连续存储的,但是函数之间却不一定是连续存储的。
每个函数方法的第一个地址,就是这个函数的入口地址,也就是说我们进行函数调用时,实际上是让CPU跳转到这个地址并执行,更加具体的就是将ip/pc寄存器的值设置为这个函数的入口地址。 对于OC类中的方法来说方法入口地址其实就是这个方法的IMP。
上面的图片中每条汇编指令都和一条机器指令唯一对应,这里要注意的是虽然显示的是汇编代码,但是真实存储和运行的还是机器代码,只不过我们通过汇编代码来展示能够容易阅读和理解而已。
每条指令前面的地址表示的是这条指令在运行时所处在的内存地址。也许你会问指令不是在CPU上吗?没有错,指令虽然是在CPU上执行,但是存储还是要在内存或者磁盘上。CPU上有一个叫ip(Intel)或者pc(arm)的寄存器保存着下一条将要执行的指令的内存地址,这样每执行一条指令时都是从ip/pc中所指定的内存地址读取出指令并执行,并同时将当前指令的下一条继续保存在ip/pc上,就这样不停重复的方式来完成指令的执行(实际上CPU为了加快处理速度会将一部分内存中的指令缓存到CPU的内部缓存中去,而不是每条指令都从内存中读取)。
符号断点
一般情况下我们可以在源代码某处设置断点来调试程序,对于没有源代码的情况下我们则可以通过设置符号断点来实现程序的调试和运行。设置符号断点在XCODE的菜单:Debug -> Breakpoints -> Create Symbolic Breakpoint 或者快捷键:option + command + \ 。
在调试运行时出现断点时可以在lldb命令行中输入各种调试命令。expr命令是p或者po的完整版本,通过expr命令除了能够用来显示外,还可以用来进行数据的修改、方法的调用等强大能力。
查看内存地址
进程中的代码和数据都保存在内存中,当我们要想一览整个进程内存中的代码和数据时,可以在程序运行时通过菜单:Debug -> Debug Workflow -> View Memory 或者通过快捷键:shift+command + m 来调用内存查看界面:
程序运行时,操作系统为其构建出一个进程,同时构建出一个虚拟的内存空间。操作系统将进程中的虚拟内存空间划分为代码存储区域、全局数据存储区域、堆存储区域、栈存储区域等区域。进程中的内存地址总是从0开始编码,并以字节为单位进行递增,直到虚拟内存空间的上限。
评论