通过arm汇编用户手册可以得知,aarch64并没有POP和PUSH的命令,只有T32和A32模式下才有,但是我们仍然可以看到aarch64下的汇编有pop指令,原因就在于这个是个转义的宏定义
arch/arm64/include/asm/assembler.h
/*
-
Stack pushing/popping (register pairs only). Equivalent to store decrement
-
before, load increment after.
*/
.macro push, xreg1, xreg2
stp \xreg1, \xreg2, [sp, #-16]! store decrement before 先自减,再保存
.endm.macro pop, xreg1, xreg2
ldp \xreg1, \xreg2, [sp], #16 load increment after先加载,再自增
.endm
这是arm STP LDP的汇编语法:
概括一下就是#imm在中括号外面的,就是postindex,在中括号里面并且有!号的,是preindex
STP Wt1, Wt2, [Xn|SP], #imm ; 32-bit, Post-index
STP Xt1, Xt2, [Xn|SP], #imm ; 64-bit, Post-index
STP Wt1, Wt2, [Xn|SP, #imm]! ; 32-bit, Pre-index
STP Xt1, Xt2, [Xn|SP, #imm]! ; 64-bit, Pre-index
STP Wt1, Wt2, [Xn|SP{, #imm}] ; 32-bit, Signed offset
STP Xt1, Xt2, [Xn|SP{, #imm}] ; 64-bit, Signed offset
LDP Wt1, Wt2, [Xn|SP], #imm ; 32-bit, Post-index
LDP Xt1, Xt2, [Xn|SP], #imm ; 64-bit, Post-index
LDP Wt1, Wt2, [Xn|SP, #imm]! ; 32-bit, Pre-index
LDP Xt1, Xt2, [Xn|SP, #imm]! ; 64-bit, Pre-index
LDP Wt1, Wt2, [Xn|SP{, #imm}] ; 32-bit, Signed offset
LDP Xt1, Xt2, [Xn|SP{, #imm}] ; 64-bit, Signed offset
preindex
这种变址方式和x86的寻址机制是很类似的,先对寄存器进行运算,然后寻址,但是在寻之后,基址寄存器的内容并不发生改变,例如:
ldr r0, [r1, #4]
的含义就是把r1+4 这个地址处的DOWRD 加载到r0,而寻址后,r1 的内容并不改变。
postindex
自然这种变址方式和i++的方式就很类似了,先利用基址寄存器进行寻址,然后对基址寄存器进行运算,其基本语法是把offset 部分放到[]外面,例如:
ldr r0, [r1], #4
就可以分解成:
ldr r0, [r1, #0]
add r1, r1, #4