【ARM】有关ARM汇编的学习笔记
ARM的寄存器:r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,r13,r14,r15
https://community.arm.com/cfs-file/__key/communityserver-blogs-components-weblogfiles/00-00-00-21-42/8463.240216_5F00_DB_5F00_ScratchRegister_2500_281_2500_29.png
看图。
r0到r3,还有r12是常用寄存器。其中r0到r3被用于函数传参,r12则是被拿来随便用,所以子过程不保证返回后它的值不变。
r0也被用于传函数返回值。
r4到r11是保留寄存器。用之前入栈,用完了出栈。
r13是栈顶,也写作sp。其实并不怎么在栈上用。
r14是链接寄存器,写作lr,它存储了程序返回的地址。
r15是指令计数器,写作pc,用于读指令。
ARM汇编与x86汇编之间做个对比:
[*]都有栈顶寄存器。
[*]ARM多了个链接寄存器,用于返回。
这一点和x86不同。x86用call来调用函数,这个过程会把返回地址压入栈,然后转到被调用的函数的入口。被调用的函数执行完了后,再用ret来返回。x86的ret从栈顶弹出返回地址到指令指针,从而返回到调用者。
而ARM的调用则是使用bl或者blx指令,它把返回地址存到链接寄存器lr,然后修改指令计数器pc。此处有个疑问:如果被调用的函数也要调用函数的话,怎么办?答案是:把链接寄存器lr入栈。这样lr就可以被嵌套使用了。而且你还可以用pop指令把栈顶上的返回地址弹出到pc上来返回,或者“返返回”,回到调用者的调用者那里去。
调用指令“bl”全名“branch with link”,“带链接的分支”。而不带链接的分支,则是“B”,跳转指令。也就是“branch”的缩写。
[*]x86使用“指令指针寄存器”eip,去“代表”执行的指令的地址。而ARM则使用“指令计数器”pc。这个pc有个特性,在后面我会说一下。
ARM的PC寄存器并不指向当前执行的指令的地址,而是指向当前执行的指令的下下一条指令的地址。
为啥要这样设计呢?因为ARM它有个三级流水线。
[*]从处取出指令。
[*]把取出的指令进行译码,也就是判断它是一条干啥的指令。
[*]知道这条指令是干啥的了以后,再执行。
ARM它并不傻乎乎地取一条执行一条。它三件事是同时执行的。每个周期,它都从处取指,并且把上一个周期取到的指令进行译码,并且执行上上一个周期译码完成的指令。
(PS:我不是在说51单片机傻)
因为这个关系,ARM的PC总是指向当前执行的指令的下下一条。也就是它正在取指的地方。就是这个地方,ARM的pc和x86的eip不同。
当ARM执行了一条跳转指令后,它就得清空这个流水线,丢掉之前取到的指令,然后重新取新的。这会导致ARM处理器不得不先懵逼两个周期,然后在第三个周期才能开始执行。所以从优化上来说,要尽量减少跳转。
参考资料:
https://community.arm.com/processors/b/blog/posts/how-to-call-a-function-from-arm-assembler
http://m.blog.csdn.net/abclixu123/article/details/7471822
PS.感谢coldzenleft给我的帮助
顶一下啊,,,有时间来慢慢学习。。。 乘简 发表于 2017-12-18 17:30
顶一下啊,,,有时间来慢慢学习。。。
这句话一听就让人觉得没时间,而且是以后也不会再有时间的那种“没时间”。可以,这很咕咕。 不知道哪里能找到编译器,有段x86的汇编代码,想改成arm汇编优化一下。 chaw899 发表于 2020-4-30 12:19
不知道哪里能找到编译器,有段x86的汇编代码,想改成arm汇编优化一下。
你把x86汇编“优化”成arm后,是要拿到手机上运行吗? 0xAA55 发表于 2020-4-30 14:37
你把x86汇编“优化”成arm后,是要拿到手机上运行吗?
是的,已经移植到手机上已经运行了。只是把汇编去掉了。
页:
[1]