天天看點

ARM64基礎7:A64的比較和跳轉指令pstate的nzcv标志位比較指令條件選擇指令基本跳轉指令帶傳回位址的跳轉指令比較并跳轉指令

pstate的nzcv标志位

條件标志位 描述
N 負數标志(上次運算結果為負值,則N=1,否則N=0)
Z 上次運算結果為0
C 對于加法運算,無符号溢出,C=1, 其他不變
V 有符号溢出
條件碼 字尾助記符 标志位 定義
0000 EQ Z=1 相等
0001 NE Z=0 不相等
0010 CS/HS C=1 無符号大于或者等于
0011 CC/LO C=0 無符号小于
0100 MI N=1 負值
0101 PL N=0 正值或0
0110 VS V=1 溢出
0111 VC V=0 無溢出
1000 HI C=1且Z=0 無符号大于
1001 LS C=0或Z=1 無符号小于或等于
1010 GE N和V相同 有符号大于或等于
1011 LT N和V不同 有符号小于
1100 GT Z=0且N等于V 有符号大于
1101 LE Z=1或N不等于V 有符号小于或等于
1110 AL 預設 無條件
1111 NV 無條件

比較指令

cmp: 比較兩個數

cmn:負向比較(一個數與另一個數的二進制補碼相比較)

cmp x1, x2 -->x1 - x2
cmn x1, x2 -->x1 + x2
           

測試代碼:

/*
 * compare lab01:test cmp and cmn
 */
.global my_cmp_cmn_test
my_cmp_cmn_test:
	mov x1, 1
	mov x2, -3
1:
	cmn x1,x2
	add x2, x2, 1
	mrs x0,nzcv
	b.mi 1b  //MI:負數

2:
	cmp x2,x1
	add x1,x1,1
	mrs x0, nzcv
	b.cs 2b  //cs:無符号大于等于

	ret
           

運作結果如下:

ARM64基礎7:A64的比較和跳轉指令pstate的nzcv标志位比較指令條件選擇指令基本跳轉指令帶傳回位址的跳轉指令比較并跳轉指令

條件選擇指令

CSEL: 條件選擇指令

CSET:條件置位指令

CSINC:條件選擇并增加指令

/* 
 * cond = true, Xd = Xn
 * cond = flase, Xd = Xm
 */
CSEL Xd, Xn, Xm, cond  

CSEL Xd, cond  //cond=true, return 1; or return 0
           
/*
 * compare lab2:
 */
.global my_csel_test
my_csel_test:
	cmp x0,0
	sub x2, x1, 1
	add x3, x1, 2
	csel x4, x3, x2, eq  //eq, ==
	mov x0, x4

	ret
           

運作結果如下:

ARM64基礎7:A64的比較和跳轉指令pstate的nzcv标志位比較指令條件選擇指令基本跳轉指令帶傳回位址的跳轉指令比較并跳轉指令

基本跳轉指令

b: 無條件跳轉,不傳回;範圍PC+/-128MB

b.cnd: 有條件跳轉,不傳回; 範圍pc+/-1MB

bx: 跳轉到寄存器指定的位址處,不傳回

帶傳回位址的跳轉指令

bl: 帶傳回位址(PC+4–>x30), 适用于調用子函數

傳回位址:儲存在X30中,父函數的PC+4

跳轉範圍:PC +/- 128MB

blx:跳轉到寄存器指定位址處,傳回位址(父函數PC+4)儲存在X30

RET: 從子函數傳回

ERET:從目前異常模式傳回,通常用于模式切換

從目前的一場模式傳回,它會從SPSR中恢複PSTATE, 從ELR中擷取跳轉位址,并傳回該位址;

測試代碼:

/*
 * compare lab2:
 */
.global my_csel_test
my_csel_test:
	cmp x0,0
	sub x2, x1, 1
	add x3, x1, 2
	csel x4, x3, x2, eq  //eq, ==
	mov x0, x4

	ret

/*
 * bl
 */
 .global my_bl_test
 my_bl_test:
 	mov x8, x30
 	mov x0, 1  // 函數嵌套調用,會沖掉x30裡儲存的傳回位址,這裡先做備份,在推出本函數時,恢複x30
 	mov x1, 3
 	bl my_csel_test

	mov x30,x8

 	ret
           

比較并跳轉指令

cbz: xt寄存器是否為0,為0則跳轉到label處,跳轉範圍+/1 1MB

cbnz: xt寄存器是否為0,不為0則跳轉到label處,跳轉範圍+/1 1MB

tbz: 測試寄存器中某位是否為0,為0則跳轉到label處,跳轉範圍+/1 32KB

tbnz: 測試寄存器中某位是否為0,為0則跳轉到label處,跳轉範圍+/1 32KB