arm64汇编解析__C函数对照

为什么要学习汇编指令

   任何高级语言, 最后都是变成汇编指令, 让机器进行执行运算的. 最早的程序也是使用汇编进行编写的.
当我们探究各种编程语言的本质时,总是离不开编程语言最后行程的产物, 也就是汇编命令.

   很多时候, 当程序发生一些难以理解的现象的时候, 通过寻常的编程语言的探索已经没有办法找到问题的根源, 这个时候通过汇编研究程序, 可能是另一个方向.

   上线的app, 电脑上运行的程序, 已经脱离了原本的编程语言, 都是最终的二进制指令. 因为二进制指令和 汇编是一一对应的. 所以我们可以通过汇编去探究程序的逻辑. 是程序逆向, 黑客不可跳过的一个环节.

arm64

  arm64指令集, 目前iOS设备基本都是这个指令集. 模拟器和mac电脑不一样.

  如果需要运行,需要在真机上跑程序.

如何学习汇编指令

   学习基本的指令与及背景知识. 然后通过c语言的和编译后的汇编的对应关系了解汇编的使用. 然后通过简单的函数编写, 加深理解.

  我们可以把水平分成2个层级,
   A: 能看懂大概
   B: 能够自己实现简单C函数逻辑
   但是如果没有自己写过汇编, 是没有办法感受其中的乐趣的.

   以下是一个简单的函数, 查看一个字符串里面的左右括号是否匹配. 一下是合法的字符串. "{[()]}" , "()[]{}"
反之,如果左右的括号不对称,则认为该字符串不合法. 比如 "}{}" "{(})" 等

.text  // 说明这是一个指令段, 
.global _isValidBrace  // 声明是向外面暴露的符号, 外面可以通过调用 isValidBrace 使用.
//  可以认为这个汇编.s文件,就是下面这个c函数的替代. 互相是等价的.
// 当然这是实现, 外面使用还需要对这个c函数进行声明, 否则编译就开始报错了.

//BOOL isValidBrace(char *s){
//    unsigned long len = strlen(s);
//    char *str = calloc(len + 1, 1);
//    int lastL = -1;
//    for (unsigned long i=0; i<len; i++) {
//        char c = s[i];
//        if (c == '(' || c== '{' || c== '[') {
//            lastL ++;
//            str[lastL] = c;
//        }else{
//            if (lastL < 0) {
//                return false;
//            }
//            char l = str[lastL];
//            if ((l=='(' && c==')') || (l=='{' && c=='}') || (l=='[' && c==']') ){
//                str[lastL] = '\0';
//                lastL --;
//            }else{
//                return false;
//            }
//        }
//    }
//    if(lastL>=0){
//        return false;
//    }
//    if(str){
//        free(str);
//        str = NULL;
//    }
//    return true;
//}
// 40  // 这几个数字分别是 ()[]{} 6个字符对应的ASCII码对应的数字
// 41
// 91
// 93
// 123
// 125
//BOOL isValidBrace(char *s);
_isValidBrace:
    // 从x0, 到 x30 都是arm64里面的寄存器. 我们可以理解为是机器层面的全局变量.
    // stp 是保存指令, store register pair, 同时保存两个寄存器. 
    // 相近的 str 也是保存指令, store register. 只能保存一个寄存器.
    // str x0, [x1]  把 x0的数据 8个字节 写入到x1寄存器的数值对应的地址开始的8个字节.
    // stp x29,x30,[sp,#-0x10]  保存x29, x30两个寄存器内数据到 sp-0x10 对应的内存地址里
    // stp x29,x30,[sp,#-0x10]!  保存结束后, sp寄存器内数据减0x10
    // x86的寄存器是2个字节, w0 是4个字节, x0是8个字节.
    // x29 = fp 是栈底指针, x30 =lr 返回地址指针.(也就是ret跳转的地址)
    // x19~x28 临时寄存器, 使用前需要保存. 不用担心调用别人的程序,这些数据会被修改. 所以是程序内安全的.
    // x9~x15, 可变寄存器, 使用的时候不需要保存.  但是在调用函数后, 数据可能会被修改. 程序内是不安全的
    // x0~x7 用于传递参数和返回数值. 超过数量的参数通过栈传递. 通过用x0传递返回值.
    stp x29,x30,[sp,#-0x10]!    // x29, x30 是
    stp x21,x22,[sp,#-0x10]!   // 后面使用x19到x22作为临时变量, 所以先保存原始数值, 程序返回前恢复.
    stp x19,x20,[sp,#-0x10]!
    stp x0,x1,[sp,#-0x10]!
    bl _strlen   // 调用 strlen 系统函数, 参数 char * s 通过x0 传入, 返回数值保存在 x0.
    mov x19,x0
    // "#"跟数字 ,标识自然数. 
    add x0,x0,#1  // >> x0 = x0+1
    mov x1,#0    // >> x1 = 0
    bl _calloc    
    mov x21,x0
    stp x19,x21,[sp,#-0x10]!  // 保存字符串长度 ; 新增加的字符串.
    mov x19,#-1 // 记录最后一个字符的位置.
    mov x20,#0
loop_str_ce:  // 标签, 用于b跳转的时候定位
    //  ldr=> load register  从内存中加载数据到寄存器,
    ldr x0,[sp,#0x10]   // 从当前的栈顶地址 +0x10的位置 读取8个字节数据, 赋值给x0. 
    // 因为这个时候需要读取函数的第一个参数, 需要重新读取, 防止x0已经被污染.
    add x0,x0,x20
    mov x1,#0
    // ldrb => load register byte. 读取一个字节. 每个字符是1个字节
    ldrb w1,[x0]  // 第i个字符
    mov x21,x1 // 记录当前的字符. x21 = x1
    cmp x1,#40  // 比较x1和#40两个数字
    b.eq equal_lbrace_ce // 如果相等, 就跳转到标签equal_lbrace_ce , 否则继续往后执行
    cmp x1,#91
    b.eq equal_lbrace_ce  
    cmp x1,#123
    b.eq equal_lbrace_ce
match_rbrace_ce:
    cmp x19,#0
    b.lt err_ret_ce  // 如果小于, 跳转, 否则继续往后执行
    
    ldr x0,[sp,#0x8] // 新字符串指针, 指向首字符.  =>  (sp+0x8) 内存地址对应的数据读取给x0
    add x0,x0,x19  // 目标支付地址
    ldrb w1,[x0]
    cmp w1,#40
    b.ne secCmp_ce
    cmp x21,#41
    b.ne err_ret_ce
    b match_ce
    
secCmp_ce:
    ldr x0,[sp,#0x8] // 新字符串指针, 指向首字符.
    add x0,x0,x19  // 目标支付地址
    ldrb w1,[x0]
    cmp w1,#91
    b.ne thirdCmp_ce
    cmp x21,#93
    b.ne err_ret_ce // 不想等时跳转
    b match_ce  // 跳转到标签, 无条件.
    
thirdCmp_ce:
    ldr x0,[sp,#0x8] // 新字符串指针, 指向首字符.
    add x0,x0,x19  // 目标支付地址
    ldrb w1,[x0]
    cmp w1,#123
    b.ne err_ret_ce
    cmp x21,#125
    b.ne err_ret_ce
    b match_ce
    
match_ce:
    mov x1,0
    strb w1,[x0]
    sub x19,x19,#1  // 减法 => x19 = x19 - #1
    
    b continu_ce  // 跳转到标签, 无条件.
equal_lbrace_ce:
    add x19,x19,#1
    ldr x0,[sp,#0x8] // 新字符串指针, 指向首字符.
    add x0,x0,x19  // 目标支付地址
    strb w1,[x0]  //保存 w1寄存器的数据最后一个字节 到x0对应的地址
continu_ce:
    add x20,x20,#1
    ldr x0,[sp]
    cmp x20,x0
    b.lt loop_str_ce
    cmp x19,#0
    b.lt nor_ret_ce
err_ret_ce:
    ldr x0,[sp,#0x8]
    bl _free
    mov x0,#0
    b last_ret
nor_ret_ce:
    ldr x0,[sp,#0x8]
    bl _free
    mov x0,#1
last_ret:
    add sp,sp,#0x40
    ldp x29,x30,[sp],#0x10
    ret

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,723评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,485评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,998评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,323评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,355评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,079评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,389评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,019评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,519评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,971评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,100评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,738评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,293评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,289评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,517评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,547评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,834评论 2 345

推荐阅读更多精彩内容

  • # 概述 早期的程序员发现机器语言在阅读、书写方面的问题,是如此的难以辨别和记忆,需要记住所有抽象的二进制码,为了...
    Tenloy阅读 5,005评论 2 10
  • 1. 机器语言 2. 汇编语言 3. 高级语言 概述:编程语言是用来定义计算机程序的形式语言,用来向计算机发出指令...
    一杯开水阅读 259评论 0 1
  • 咱们本篇文章讲的语法不多,因为语法已经有很多文章可以参考学习,本篇主要讲的是怎么去理解汇编。 首先了解计算机结构 ...
    黑色蚂蚁_MGL阅读 2,738评论 0 3
  • 在定位某些crash问题的时候,有时候遇到一些问题很诡异。有时候挂在了系统库里面。这个时候定位crash问题往往是...
    一川烟草i蓑衣阅读 1,200评论 0 2
  • 在定位某些crash问题的时候,有时候遇到一些问题很诡异。有时候挂在了系统库里面。这个时候定位crash问题往往是...
    kakukeme阅读 6,590评论 0 58