汇编的简单知识

原创文章
声明:作者声明此文章为原创,未经作者同意,请勿转载,若转载,务必注明本站出处,本平台保留追究侵权法律责任的权利。
全栈老韩
全栈工程师,擅长iOS App开发、前端(vue、react、nuxt、小程序&Taro)开发、Flutter、React Native、后端(midwayjs、golang、express、koa)开发、docker容器、seo优化等。

汇编

  1. 汇编语言与机器语言一一对应,每一条机器指令都有与之对应的汇编指令;

  2. 汇编语言可以通过编译得到机器语言,机器语言可以通过反汇编得到汇编语言

  3. 高级语言可以通过编译得到汇编语言/机器语言,但汇编语言/机器语言几乎不可能换成成高级语言

  4. 修改pc通用寄存器的指令:

    register write pc 0x...

CPU从何处执行指令是由pc中的内容决定的,我们可以通过改变pc的内容来控制CPU执行目标指令

ARM64提供了一个mov指令(传送指令),可以用来修改大部分寄存器的值,比如:
move x0, #10、mov x1,#20

但是mov指令不能用于设置pc的值,ARM64没有提供这样的功能

ARM64提供了另外的指令来修改pc的值,这些指令通称为转移指令,最简单的是bl指令

Example

复制代码
// 1. 新建assembly file: asm.s

.text
.global _A,_B

_A:
    mov x0, #0xa0
    mov x1, #0x00
    add x1,x0,#0x14
    bl _B
    mov x0,#0x0
    ret
    
_B:
    add x0,x0,#0x10
    ret
    
// 2. 在main.m中
void A();
int main(int argc, char * argv[]) {
    A();
}

上述代码会造成死循环,由于ret是在lr(x30)寄存器中告诉cpu下一条指令的地址,所以会造成在A和B之间重复调用。

修改代码:

复制代码
// 1. 新建assembly file: asm.s

.text
.global _A,_B

_A:
    str x30,[sp #-0x10]! // 感叹号的作用是先执行数据的存放,再进行减
    bl _B
    mov x0, #0xa0
    ldr x30, [sp], #0x10
    ret
    
_B:
    add x0,x0,#0x10
    ret
    
// 2. 在main.m中
void A();
int main(int argc, char * argv[]) {
    A();
}

函数本质


  • LIFO后进先出

暂无评论,快来发表第一条评论吧