汇编指令
| 标题 | 高级语言描述 |
|---|---|
| mov ax, bx | ax=bx |
| add ax, bx | ax = ax + bx |
| bl | 跳转指令,但跳转之前,会在寄存器R14 中保存PC 的当前内容,因此,可以通过将R14 的内容重新加载到PC 中,来返回到跳转指令之后的那个指令处执行。该指令是实现子程序调用的一个基本但常用的手段。 |
| B | 最简单的跳转指令。一旦遇到一个 B 指令,ARM 处理器将立即跳转到给定的目标地址,从那里继续执行。 |
| uxtb | 将4个字节的其中一个字节提取出来,然后转成一个新的32位整型 |
| ret | 相当于高级语言的return |
6f615c: d00057e3 adrp x3, 11f4000 <_ZZN7cocos2d13AsyncTaskPool11ThreadTasks7enqueueESt8functionIFvPvEES3_S2_IFvvEEE12__FUNCTION__+0x4a60>
6f6160: 52800041 mov w1, #0x2 // #2
6f6164: 9100dfa2 add x2, x29, #0x37
6f6168: 913de063 add x3, x3, #0xf78
6f616c: 97ff8ad0 bl 6d8cac <_Z17luaval_to_booleanP9lua_StateiPbPKc>
6f6170: 53001c00 uxtb w0, w0
6f6174: 35000100 cbnz w0, 6f6194 <_Z28lua_cocos2dx_Node_setVisibleP9lua_State+0xc8> // 对应的是这里
6f6178: d00057e1 adrp x1, 11f4000 <_ZZN7cocos2d13AsyncTaskPool11ThreadTasks7enqueueESt8functionIFvPvEES3_S2_IFvvEEE12__FUNCTION__+0x4a60>
6f617c: aa1503e0 mov x0, x21
6f6180: 913e4021 add x1, x1, #0xf90
6f6184: d2800002 mov x2, #0x0 // #0
6f6188: 9403ee4f bl 7f1ac4 <tolua_error>
6f618c: 52800000 mov w0, #0x0 // #0
6f6190: 17ffffea b 6f6138 <_Z28lua_cocos2dx_Node_setVisibleP9lua_State+0x6c>
6f6194: f94002c2 ldr x2, [x22]
6f6198: aa1603e0 mov x0, x22
6f619c: 3940dfa1 ldrb w1, [x29,#55]
6f61a0: f940b842 ldr x2, [x2,#368]
6f61a4: d63f0040 blr x2
6f61a8: aa1503e0 mov x0, x21
6f61ac: 2a1403e1 mov w1, w20
6f61b0: 940e4738 bl a87e90 <lua_settop>
6f61b4: 2a1403e0 mov w0, w20
6f61b8: 17ffffe0 b 6f6138 <_Z28lua_cocos2dx_Node_setVisibleP9lua_State+0x6c>
6f61bc: 97f8471d bl 507e30 <__stack_chk_fail@plt>
编译器函数名称修饰符
是为了保证函数名字的唯一性。
_Z28lua_cocos2dx_Node_setVisibleP9lua_State
P 是指针参数的意思
-
全局函数: 以“_Z”开头,然后是函数名字符的个数28,"lua_cocos2dx_Node_setVisible".length=28,,接着是函数名,最后是函数参数的别名。
-
类、命名空间中的变量函数
以“_ZN”开头,然后是变量或函数所在名字空间或类名字的字符长度,然后接着的是真正的名字空间或类名,然后是变量或函数名的长度和变量或函数名,后面紧跟字母“E”,最后如果是函数的话则跟参数别名,如果是变量则什么都不用加。
- 构造函数和析构函数
以”_ZN”开头,然后是构造函数所在名字空间和类名字的字符长度,然后接着的是真正的名字空间或类名,然后构造函数接“C1”或者“C2”,析构函数接“D1”或者“D2”,然后加上字母“E”,最后接函数参数别名结束。
int lua_cocos2dx_Node_setVisible(lua_State* tolua_S)
立即数
立即数就是写在指令里的常数。 还是用mov操作举例子,mov 12, %rax,那么这个 12 就在操作语句里。那么 12 相当于指令里的立即数。
汇编基础知识
7f1018: 940a5b9e bl a87e90 <lua_settop>
操作码(94对应arm指令bl) 条件码(0a无条件跳转) 偏移量(5b9e)
7f1018+5b9e=7F6BB6
↓ 这个地址,对应的就是lua_settop的地址
7f1018: 940a5b9e bl a87e90 <lua_settop>
0000000000a87e90 <lua_settop>:
a87e90: d10083ff sub sp, sp, #0x20
a87e94: a90053f3 stp x19, x20, [sp]
a87e98: f9000bfe str x30, [sp,#16]
a87e9c: aa0003f3 mov x19, x0
a87ea0: 37f80381 tbnz w1, #31, a87f10 <lua_settop+0x80>
a87ea4: f9401004 ldr x4, [x0,#32]
a87ea8: 937d7c34 sbfiz x20, x1, #3, #32
a87eac: f9401402 ldr x2, [x0,#40]
str指令
str x2, [x29,#72]
STR指令用于从源寄存器x2中将一个32位的字数据传送到存储器中x29中
stp 指令是 str 的变种指令,p 可以理解成 pair 的意思,可以同时操作两个寄存器。
- FP:栈顶指针,指向一个栈帧的顶部,当函数发生跳转时,会记录当时的栈的起始位置。
- SP:栈指针(也称为栈底指针),指向栈当前的位置,
- LR:链接寄存器,保存函数返回的地址。
寄存器名全部是 x1 、 x2 、 x10 了。