参考:https://bbs.pediy.com/thread-224583.htm
整理成表格方便查询
cdecl(C规范),
stdcall(WinAPI默认),
fastcall,
ATPCS(ARM-Thumb Procedure Call Standard/ARM-Thumb过程调用标准) ,
thiscall(用于C++中类成员函数)
调用约定架构 | X86 | X64 | ARM | AARCH64 |
cdecl | 参数从右往左依次入栈,调用者实现栈平衡,返回值存放在 EAX 中。 | X | X | X |
stdcall | 参数从右往左依次入栈,被调用者实现栈平衡,返回值存放在 EAX 中。 | X | X | X |
fastcall |
参数1~参数2 分别保存在 ECX、EDX , 剩下的参数从右往左依次入栈, 被调用者实现栈平衡, 返回值存放在 EAX 中。 |
参数1~参数4 分别保存在 RCX、RDX、R8D、R9D , 剩下的参数从右往左依次入栈, 被调用者实现栈平衡, 返回值存放在 RAX 中。 |
X | X |
thiscall |
参数从右往左依次入栈, this指针存放ECX中, 被调用者实现栈平衡, 返回值存放在 EAX 中。 |
参数1~参数3 分别保存在RDX、R8D、R9D中, this指针存放RCX中, 剩下的参数从右往左依次入栈, 被调用者实现栈平衡, 返回值存放在 RAX 中。 |
(C++) 参数1~参数3 分别保存在R1~R3中, this指针存放R0中, 剩下的参数从右往左依次入栈, 被调用者实现栈平衡, 返回值存放在 R0 中。 |
(C++) 参数1~参数7 分别保存到 X1~X7 寄存器中, this指针存放X0中, 剩下的参数从右往左依次入栈, 被调用者实现栈平衡, 返回值存放在 X0 中。 |
ATPCS | X | X |
(C语言) 参数1~参数4 分别保存到 R0~R3 寄存器中 , 剩下的参数从右往左依次入栈, 被调用者实现栈平衡, 返回值存放在 R0 中。 |
(C语言) 参数1~参数8 分别保存到 X0~X7 寄存器中 , 剩下的参数从右往左依次入栈, 被调用者实现栈平衡, 返回值存放在 X0 中。 |
ARM相关的杂项记录:
ARM 32 64位 指令 B BL BX BR BLX BLR 的区别
2種跳法
立即数跳(标记的地址為指令的參數)
寄存器跳(PC的值由參數寄存器給出)
指令集 | A32/A64 | A32/A64 | A64 | |
保存LR(返回地址) 類似X86的CALL |
BL 立即数相對跳 效果: X30=PC + 4 PC=PC+LABEL |
BLX 立即数相對跳 效果: X30=PC + 4 PC=PC+LABEL 切換指令集 寄存器跳 效果: X30=PC + 4 PC=Xn 切換指令集 |
BLR 寄存器跳 效果: X30=PC + 4 PC=Xn |
|
不保存LR(返回地址) 類似X86的JMP |
B 立即数相對跳 效果: PC=PC+LABEL |
BX 寄存器跳 效果: PC=Xn 切換指令集 |
BR 寄存器跳 效果: PC=Xn |
带X 的:BX BLX 会根据给出的地址的最后一位[0]判断 =0切换为ARM指令模式,=1切换为Thumb指令模式
64位的 RET指令 = mov pc,x30. x30=LR, 一般配合带L的跳转,如BL,BLX,BLR
立即數相對跳中 ,LABEL相對當前PC的地址範圍 在 A64 LABEL = ±128MB ,在 A32 下 LABEL = ±32MB
參考:http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0802b/Cihfddaf.html
執行狀態切換
对于A32来说,ARM和thumb的切换,通过bx指令即可切换。但是对于A64和A32两种执行状态,只能通过异常,进行切换。
-
切换到低EL,执行状态要么保持,要么切换到A32
-
切换到高EL,执行状态要么保持,要么切换到A64
如操作系統在EL1是 A32,那麽應用程序在EL0的話,只能是A32狀態,即使你的芯片支持A64
如操作系統在EL1是 A64,那麽應用程序在EL0的話,能是A32或A64狀態 ,如android 的 linker (A32) 和 linker64(A64)