1 状态寄存器CPSR
ARM64下,寄存器32位,高4位N、Z、C、V均为条件码标志位。 SUBS和ADDS影响CPSR,而SUB和ADD则不影响
2 TEST
属于逻辑操作指令,影响结果CPSR 如果与计算结果为0,则Z标志为1,否则为0 Test例如,寄存器用于测试一个位置 test eax, 100b; b后缀是二进制 jnz **; 如果eax右数第三位为1,jnz将会跳转
3 CMP
属于算术操作指令,做减法,但与SUB不同的指令是SUB指令执行过以后,原来寄存器中的被减数丢了,被换成了减法的结果,CMP指令执行后,减数和减数保持不变。 CMP指令影响CPSR 当比较结果为0时,即相等,Z位置1。 arm跳下条件 表达式 英文 中文 bl.eq equal 等于 bl.ne not equal 不等于 bl.gt greater than 大于 bl.ge greater equal 大于等于 bl.lt less than 小于 bl.le less equal 小于等于
x86下的跳转 je equal 等于 jne not equal 不等于 jg greater 大于 jge greater equal 大于等于 jl less 小于 jle less equal 小于等于
call 为x86的跳转指令 bl 为arm的跳转指令
其他
adrp 指令,将pc低12位清零,然后立即向左移动12位 adrp x8, 10,此时pc 0x00000001026c4478 x8 = 0x00000001026c4000 0xa000 = 0x00000001026ce000
在第一次由adrp获取页面的基址(即获取页面的基址)lable,本例10),然后在页面中添加偏移,以获得最终值。
br Xm:跳转到由Xm目标寄存器指定的地址。 blr Xm:跳转到由Xm将下一个指令存储在目标寄存器指定的地址上X30(lr)例如:blr x跳转后,即lr存放着blr x下一个指令20。 b label,跳转到标签(内外,外指C函数)。 bl label,跳转到标签(内部或外部,外部指C函数),并将下一个指令存储在X30(lr)寄存器中。
__asm volatile ("br x8\n"); void mytest(int a, int b) { } __asm volatile ("bl _mytest\n"); stp x8, x9, [sp, #-32]! //把x8,x9 的值存到sp-32的地址后,sp=sp-32 stp x8, x9, [sp], #-0x10 //把x8,x9 的值存到sp的地址后,sp=sp 16 stp x8, x9, [sp, #16] //把x8,x9 的值存到sp 16的地址中 ldp x0, x1, [sp], #0x10 // 把sp读取地址内容x0,x1后,sp=sp 16 ldp x0, x1, [sp, #0x10]! // 把sp 读取16的内容x0,x1后,sp=sp 16 ldp x19, x20, [sp, #16] // sp 16 地址值分别放回x19 x20
sp和偏移在一个括号内,地址是sp 偏移,后跟!操作完成后,sp自动变化,否则不变。 sp单独括号,地址是sp,操作完成后sp会自动变化。
asm volatile ( "adrp x0, _func@PAGE\n" "add x0,x0,_func@PAGEOFF\n" ); 将func加载地址x0寄存器中 cbz x0, LGetImpMiss // x0为 0则跳转到LGetImpMiss。C函数只能内跳,不能外跳。 cbz: xt寄存器是0,0跳转到0label跳转范围 /1 1MB cbnz: xt寄存器是0吗?如果不是0,跳转到0label跳转范围 /1 1MB tbz: 测试寄存器中的一个是否为0,为0跳转label跳转范围 /1 32KB tbnz: 测试寄存器中某位是否为0,为0则跳转到label跳转范围 /1 32KB ubfx x11, x0, #60, #4 //取x0的高4位到x11 ldr x13, [x0] // 加载x0内容到x13寄存器 lip 将内容加载到2个64寄存器 汇编调用c时,在函数前加下划线_ 在汇编前加下划线_,c调用汇编时不添加下划线_