ARM instruction misc
. daifset/daifclr
msr daifset, #0xf //对DAIF寄存器的值的bit0-3位置1
msr daifset, #2 //对DAIF的bit1置1,即对DAIF的I bit置1(disable irq)
tbnz
指令 |
使用范例 |
功能描述 |
---|---|---|
CBZ |
CBZ X1, label |
如果x1 == 0,则跳转到label |
CBNZ |
CBNZ X1, label |
如果x1 != 0,则跳转到label |
TBZ |
TBZ X1, #3, label |
如果x1寄存器的第三位等于0,则跳转到label |
TBNZ |
TBNZ X1, #3, label |
如果x1寄存器的第三位不等于0,则跳转到label |
from: https://support.huaweicloud.com/pinsrcase-kunpengprocs/kunpengprocessor_18_0040.html
.align 7
经常会看到arm-linux汇编中有如下的指令: .align n 它的含义就是使得下面的代码按一定规则对齐,.align n 指令的对齐值有两种方案,n 或 2^n ,各种平台最初的汇编器一般都不是gas,采取方案1或2的都很多。
PRFM
Prefetch from Memory (PRFM) provides a hint to the memory system that data from a particular address will be used by the program soon. The effect of this hint typically results in data or instructions being loaded into one of the caches.
The instruction syntax is:
PRFM <prfop>, <addr> | label
Where prfop is a concatenation of the following options:
Type PLD or PST (prefetch for load or store).
Target L1, L2, or L3 (which cache to target).
Policy KEEP or STRM (keep in cache, or streaming data).
For example, PLDL1KEEP.
AArch64: PRFM PLDL1KEEP, [Xm, #imm] ; This indicates a Prefetch for a load from Xm +
offset into the L1 cache as a temporal prefetch, which means that the data might be used
more than once.
LDAXR
LDAXRB是byte;LDAXRH是half-word;LDAXR是register:
A register instruction operates on a doubleword if accessing an X register, or on a word if accessing a W register
stxr ws, <wt/xt>, [Xn]
arm64指令,STXR指令和普通的STR指令,不同的是,该指令有返回值,表示store exclusive是否成功。如果成功,ws为0,不成功,ws为1。
ldp x29, x30, [sp],#16
ldp x29, x30, [sp],#16:从sp的位置提取数据到x29、x30,x29在低地址、x30在高地址,执行完以后,sp加上0x10,隐藏着出栈的操作指令
ARM NZCV标志位
之前以为CMP指令执行后,不管是进位还是借位,C标志位都会置位,其实这是错的,所以我整理了一下四个ARM标志位的置位和清零的规则:
N 当用两个补码表示的带符号数进行运算时,N=1表示运算的结果为负数;N=0表示运算的结果为正数或零.
Z Z=1表示运算的结果为零,Z=0表示运算的结果非零。
C 可以有4种方法设置C的值:
加法运算(包括CMN):当运算结果产生了进位时(无符号数溢出),C=1,否则C=0。
减法运算(包括CMP):当运算时产生了借位时(无符号数溢出),C=0,否则C=1。
对于包含移位操作的非加/减运算指令,C为移出值的最后一位。
对于其它的非加/减运算指令,C的值通常不会改变。
V 可以有2种方法设置V的值:
对于加减法运算指令,当操作数和运算结果为二进制的补码表示的带符号数时,V=1表示符号位溢出
对于其它的非加/减运算指令,V的值通常不会改变。
0000 = EQ - Z set (equal,相等)
0001 = NE - Z clear (not equal,不相等)
0010 = CS - C set (unsigned higher or same,无符号大于或等于)
0011 = CC - C clear (unsigned lower,无符号小于)
0100 = MI - N set (negative,负数)
0101 = PL - N clear (positive or zero,正数或零)
0110 = VS - V set (overflow,溢出)
0111 = VC - V clear (no overflow,未溢出)
1000 = HI - C set and Z clear (unsigned higher,无符号大于)
1001 = LS - C clear or Z set (unsigned lower or same,无符号小于或等于)
1010 = GE - N set and V set, or N clear and V clear (greater or equal,带符号大于或等于)
1011 = LT - N set and V clear, or N clear and V set (less than,带符号小于)
1100 = GT - Z clear, and either N set and V set, or N clear and V clear (greater than,带符号大于)
1101 = LE - Z set, or N set and V clear, or N clear and V set (less than or equal,带符号小于或等于)
1110 = AL - always
1111 = NV - never
from:
https://blog.csdn.net/nanfangqiulin/article/details/51122718
movk
这两个有时有时一个接一个地使用。它们用于移动立即数。 MOVZ将立即数(16位值)移至寄存器,并且该立即数之外的所有其他位均设置为零。可以将立即数向左移0、16、32或48。MOVK移动并立即取值,但保持寄存器的其他位不变。例如,假设您需要将此值移动0x7fb7fb1f88来注册X0。首先,您将使用MOVZ指令移动前16位(位0到15),因此寄存器的其余部分设置为零。然后,您将使用MOVK指令移动后16位(第16到31位),因此之前移动的值(前16位)保留在寄存器中,其余的其余位也是如此。
instruction value of x0 mov x0, #0x1f88 | 0x1f88 movk x0, #0xb7fb, lsl #16 | 0xb7fb1f88 movk x0, #0x7f, lsl #32 | 0x7fb7fb1f88
brk #imm16
brk指令执行后将产生一个异常,一个同步异常
brk fault EC是0x3C
static struct break_hook bug_break_hook = { .esr_val = 0xf2000000 | BUG_BRK_IMM, .esr_mask = 0xffffffff, .fn = bug_handler, };