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
運作結果如下:
條件選擇指令
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
運作結果如下:
基本跳轉指令
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