• iOS查看汇编代码


    在iOS开发过程中,断点调试是我们常用的方法, 除了Objective-C/Swift的调试外,有时也需要用到汇编调试,比如在查看系统库的调用堆栈。许多大型的iOS工程师已经完成组件化,在使用二进制framework方式引入其他模块的时候,我们无法直接查看源码,通过汇编,我们可以看到调用堆栈,并且借助调试命令,我们可以查看调用方法的传参。本文介绍iOS工程如何查看汇编代码。

    打开iOS工程,在Xcode的Debug菜单,点击Debug Workflow,勾选Always Show Disassembly

    在这里插入图片描述
    在工程代码适当位置加断点,启动项目,执行到代码断点时,即可查看当前堆栈的汇编代码

    我们在ViewController的viewDidLoad方法添加如下代码

    - (void)viewDidLoad {
        [super viewDidLoad];
    
        [self testMethod:@"test"];
    }
    
    - (void)testMethod:(NSString *)string
    {
        NSLog(@"%@", string);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    在[self testMethod:@“test”];这一行前面添加断点,程序执行到这一行的时候,Xcode界面直接展示了汇编代码。

    iOSProject`-[ViewController viewDidLoad]:
        <+0>:  pushq  %rbp
        <+1>:  movq   %rsp, %rbp
        <+4>:  subq   $0x20, %rsp
        <+8>:  movq   %rdi, -0x8(%rbp)
        <+12>: movq   %rsi, -0x10(%rbp)
        <+16>: movq   -0x8(%rbp), %rax
        <+20>: movq   %rax, -0x20(%rbp)
        <+24>: movq   0x49711(%rip), %rax       ; (void *)0x0000000105d77bc8: ViewController
        <+31>: movq   %rax, -0x18(%rbp)
        <+35>: movq   0x47fd6(%rip), %rsi       ; "viewDidLoad"
        <+42>: leaq   -0x20(%rbp), %rdi
        <+46>: callq  0x105d5e69e               ; symbol stub for: objc_msgSendSuper2
    ->  <+51>: movq   -0x8(%rbp), %rdi
        <+55>: movq   0x47fca(%rip), %rsi       ; "testMethod:"
        <+62>: leaq   0x3bcbb(%rip), %rdx       ; @"test"
        <+69>: callq  *0x3b40d(%rip)            ; (void *)0x00007fff20185480: objc_msgSend
        <+75>: addq   $0x20, %rsp
        <+79>: popq   %rbp
        <+80>: retq   
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    从汇编代码中可以看到,当前的实例对象是ViewController的实例,当前调用了viewDidLoad方法,并且调用了super的viewDidLoad方法,接下来调用的是testMethod:方法,参数为@“test”,Objective-C的方法底层调用的是objc_msgSend方法。

    点击step into执行汇编代码,在命令行里面,输入register read指令,可以查看所有寄存器的取值。

    从汇编语言的代码可以看到,里面使用了诸多的汇编指令和寄存器。iOS模拟器实际使用的MacOS的程序,如果是Intel芯片的mac电脑,那么展示的是x86风格的汇编代码。这里有汇编常用的指令和寄存器列表。

    指令

    数据传送

    movq ra, rb

    pushq r;把寄存器压入堆栈

    popq r;把寄存器弹出堆栈

    算术和逻辑运算

    addq 相加

    mulq ax, r 乘法运算

    incqdecq 自增,自减

    cmpq ra, rb 比较

    andqorqxorq 与,或,异或

    转移指令

    jmp label

    callq label 过程调用

    retq 过程返回

    寄存器

    ESP:堆栈指针寄存器

    EBP:基址指针寄存器

    EAX:累加寄存器

    EBX:基址寄存器

    ECX:计数寄存器

    EDX:存放数据寄存器

    ESI:源变址寄存器

    EDI:目标变址寄存器

  • 相关阅读:
    主机加固,防勒索病毒
    UML概述及UML类图详解
    队列——算法专项刷题(七)
    一种简单的三维重建算法的实现【源码】
    【camera】【ISP】Lens Shading Correction镜头阴影校正
    rust 字符串字面量 - 字符串前缀
    Shiziku 开启adb权限 之 三星S10+ 主板机
    第二章 数据库设计
    Leetcode—2331.计算布尔二叉树的值【简单】
    23种设计模式之状态模式(State Pattern)
  • 原文地址:https://blog.csdn.net/u011608357/article/details/126209395