arm64汇编学习 - (5)比较跳转指令2
本篇博客是基于对苯叔的第三季视频的学习整理而得,大家如果想深入学习可以购买《arm64体系结构编程与实践》以及购买苯叔出品的第三季视频。
1 基本跳转指令
1.1 B
Branch causes an unconditional branch to a label at a PC-relative offset, with a hint that this is not a subroutine call or return.
26-bit signed PC-relative branch offset variant
B <label>
Decode for this encoding
bits(64) offset = SignExtend(imm26:'00', 64);
Assembler symbols
- Is one of the standard conditions, encoded in the “cond” field in the standard way.
1.2 BR
Branch to Register branches unconditionally to an address in a register, with a hint that this is not a subroutine return.
Integer variant
BR <Xn>
Decode for this encoding
integer n = UInt(Rn);
Assembler symbols
Is the 64-bit name of the general-purpose register holding the address to be branched to, encoded in the “Rn” field.
Operation
bits(64) target = X[n];
BranchTo(target, BranchType_INDIR);
2 有条件跳转指令B.cond
Branch conditionally to a label at a PC-relative offset, with a hint that this is not a subroutine call or return.
19-bit signed PC-relative branch offset variant
B.<cond> <label>
Decode for this encoding
bits(64) offset = SignExtend(imm19:'00', 64);
Assembler symbols
- Is one of the standard conditions, encoded in the “cond” field in the standard way.
3 带返回地址的跳转指令
3.1 bl
Branch with Link branches to a PC-relative offset, setting the register X30 to PC+4. It provides a hint that this is a subroutine call.
26-bit signed PC-relative branch offset variant
BL <label>
Decode for this encoding
bits(64) offset = SignExtend(imm26:'00', 64);
Assembler symbols
Operation
X[30] = PC[] + 4;
BranchTo(PC[] + offset, BranchType_DIRCALL);
3.2 BLR
Branch with Link to Register calls a subroutine at an address in a register, setting register X30 to PC+4.
Integer variant
BLR <Xn>
Decode for this encoding
integer n = UInt(Rn);
Assembler symbols
Is the 64-bit name of the general-purpose register holding the address to be branched to, encoded in the “Rn” field.
Operation
bits(64) target = X[n];
X[30] = PC[] + 4;
BranchTo(target, BranchType_INDCALL);
4 比较并跳转指令
4.1 cbnz
Compare and Branch on Nonzero compares the value in a register with zero, and conditionally branches to a label at a PC-relative offset if the comparison is not equal. It provides a hint that this is not a subroutine call or return.
This instruction does not affect the condition flags.
32-bit variant
Applies when sf == 0.
CBNZ <Wt>, <label>
64-bit variant
Applies when sf == 1.
CBNZ <Xt>, <label>
Operation
bits(datasize) operand1 = X[t];
if IsZero(operand1) == FALSE then
BranchTo(PC[] + offset, BranchType_DIR);
4.2 cbz
Compare and Branch on Zero compares the value in a register with zero, and conditionally branches to a label at a PC-relative offset if the comparison is equal. It provides a hint that this is not a subroutine call or return. This instruction does not affect condition flags.
32-bit variant
Applies when sf == 0.
CBZ <Wt>, <label>
64-bit variant
Applies when sf == 1.
CBZ <Xt>, <label>
Operation
bits(datasize) operand1 = X[t];
if IsZero(operand1) == TRUE then
BranchTo(PC[] + offset, BranchType_DIR);
4.1 tbnz
Test bit and Branch if Nonzero compares the value of a bit in a general-purpose register with zero, and conditionally branches to a label at a PC-relative offset if the comparison is not equal. It provides a hint that this is not a subroutine call or return. This instruction does not affect condition flags.
14-bit signed PC-relative branch offset variant
TBNZ <R><t>, #<imm>, <label>
Decode for this encoding
integer t = UInt(Rt);
integer datasize = if b5 == '1' then 64 else 32;
integer bit_pos = UInt(b5:b40);
bits(64) offset = SignExtend(imm14:'00', 64);
Operation
bits(datasize) operand = X[t];
if operand<bit_pos> == op then
BranchTo(PC[] + offset, BranchType_DIR);
4.1 tbz
Test bit and Branch if Zero compares the value of a test bit with zero, and conditionally branches to a label at a PC-relative offset if the comparison is equal. It provides a hint that this is not a subroutine call or return. This instruction does not affect condition flags.
14-bit signed PC-relative branch offset variant
TBZ <R><t>, #<imm>, <label>
Decode for this encoding
integer t = UInt(Rt);
integer datasize = if b5 == '1' then 64 else 32;
integer bit_pos = UInt(b5:b40);
bits(64) offset = SignExtend(imm14:'00', 64);
Operation
bits(datasize) operand = X[t];
if operand<bit_pos> == op then
BranchTo(PC[] + offset, BranchType_DIR);