分享

ARMarch64汇编学习笔记 · Cocoa

 望穿墙 2016-06-26

转:

ARMarch64汇编学习笔记

30 Aug 2015
__uint64_t __x[29];	/* General purpose registers x0-x28 */
__uint64_t __fp;	/* Frame pointer x29 */
__uint64_t __lr;	/* Link register x30 */
__uint64_t __sp;	/* Stack pointer x31 */
__uint64_t __pc;	/* Program counter */
__uint32_t __cpsr;	/* Current program status register */
__uint32_t __pad; /* Same size for 32-bit or 64-bit clients */
32位的ldm,stm,push,pop指令在64位中不存在.
ldm,stm本来的作用是批量出栈进栈.//详细:http://blog./uid-25100840-id-340479.html
例子:
   LDMFD     SP! ,  {R0, R1, R2} //把sp指向的地址和后2个,就是总共3个连续内存数据拷到3个寄存器中.
   STMFD     SP!,   {R0} //把r0拷到sp指向的地址(堆栈)中.如果2个或2个以上寄存器,就是拷到后连续地址这样,总之和ldm对应.
取而代之的是ldp,stp也是这个作用.而且使用很频繁.一般使用在函数开头使用代替push.
例子:
stp        x29, x30, [sp, #0xfffffff0]!
ldp        x29, x30, [sp], #0x10

感叹号的意思是先运算修改寄存器的值,再使用寄存器.
没有感叹号就像下面这个例子.每次使用完sp的值后加上0x10.这样就可以省略armv7里add sp,#0x40的操作了.
ffffff8012ae5770         ldp        x24, x23, [sp], #0x10
ffffff8012ae5774         ldp        x22, x21, [sp], #0x10
ffffff8012ae5778         ldp        x20, x19, [sp], #0x10
ffffff8012ae577c         ldp        x29, x30, [sp], #0x10

从可用寄存器角度来说,程序员可以完全使用31个通用寄存器(X0-X30或W0-W30),而堆栈指针寄存器(SP或WSP)以及指令指针寄存器IP都是独立的,这个与32位的不同(R13为堆栈指针寄存器,R15作为指令指针寄存器)。对于ARM官方提供的调用约定,参数可以用8个寄存器(X0-X7或W0-W7)。这意味着64位下,即便传8个参数都能进寄存器,呵呵。而需要被当前例程所保护的通用寄存器是从X18到X30。不过少了原来的push/pop指令,原来的push能一次将几乎所有通用寄存器保存到栈上。现在如果要保存通用寄存器到栈上的话一般使用LDP/STP指令对SP操作,这样可以同时加载/存储两个64位寄存器。用这对指令同时也能确保栈地址始终能16字节对齐。 而对于SIMD寄存器以及浮点寄存器来说,除了标量单精度与双精度寄存器的数量不变以为(它俩仍然与SIMD寄存器共享),SIMD寄存器由原先32位下的16个扩充到了32个。在32位下,需要被保护的SIMD寄存器是Q4-Q7这四个,而64位下,需要被当前例程所保护的SIMD寄存器是V8-V15。

从ISA角度上来说,原本32位下有很强悍的几乎每条指令都带条件操作的特性完全木有了~留下几条含有前缀C的比较简单常用的操作,比如CCMP、CSEL、CINC、CINV等。不过像算术逻辑操作仍然有不改变当前标志位与改变当前标志位两种版本,这点还是很不错的。在64位下,Thumb指令集全都没有了,所有指令都是32位宽。因此立即数与ARMv7比起来,除了移位还算正常,其它的都显得有些奇葩

简单点:传参寄存器增加到8个,push,pop用stp,ldp.看代码要注意些小心些.

arm结构 寄存器:arm64有32个64bit长度的通用寄存器x0~x30,sp,可以只使用其中的32bit w0~w30,arm32只有16个32bit的通用寄存器r0~r12, lr, pc, sp. arm64有32个128bitSIMD寄存器v0~v31,arm32有16个128bitSIMD寄存器Q0~Q15,又可细分为32个64bitSIMD寄存器D0~D31 函数调用:arm64前面8个参数都是通过寄存器来传递x0~x7, arm32前面4个参数通过寄存器来传递r0~r3,其他通过栈传递

指令集:arm64和arm32是两套不同的指令集,尤其是SIMD指令集完全不同。

这里再记些常用的指令(不是只为armv8): adr:功能和ldr差不多.相当于小范围内的读取.有时会直接从立即数读取.

例子:

adrp       x20, #0xffffff8012bda000                    ; 0xffffff8012bda000 
add        x20, x20, #0xdb2                            ; "init"
mov        x0, x20
bl         _strlen

差不多就那样了.看多就会了嘛

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多