索引:鼠标右键上拉可回来
1、写在前面的话
这篇博客主要承接上文,整理下ARM汇编中的数据处理指令,这次指令主要包括逻辑运算指令、比较指令等,下面详细归类说明下。
2、逻辑运算指令
逻辑运算是对操作数按位进行操作的,位与位之间没有进位或者错位,没有数的正负与数的大小之分,这种运算的操作数称为逻辑数或逻辑值。逻辑运算主要包括:
AND–逻辑与指令
ORR–逻辑或指令
EOR–逻辑异或指令
BIC–位清除指令
01 AND指令
格式:AND{<cond>}{S} Rd, Rn, operand2
用法:将两个操作数按位进行逻辑与运算,结果放到目标寄存器Rd中,相当于Rd = Rn AND operand2。其中Rn是操作数1,是一个寄存器;operand2为操作数2,可以是一个寄存器、被移位的寄存器或一个立即数。
示例:
AND R0, R0, #0xF ; 保持R0的低4位,其余位清零,执行后R0 = 0x0000000F(32位)
备注:
01 S选项决定了指令的操作是否影响CPSR中条件标志位的值,有S时指令执行后的结果影响CPSR中条件标志位N和Z的值。
02 在计算第2操作数时更新标志C,不影响V标志。
03 该指令通常用于将操作数1的特定位清零的操作。
02 ORR指令
格式:ORR{<cond>}{S} Rd, Rn, operand2
用法:将两个操作数按位进行逻辑或运算,结果放到目标寄存器Rd中,相当于Rd = Rn ORR operand2,其中Rn是操作数1,是一个寄存器;operand2为操作数2,可以是一个寄存器、被移位的寄存器或一个立即数。
示例:
ORR R0, R0, #5 ; 将R0的第0位和第3位设置为1,其余位不变
备注:
01 S选项决定了指令的操作是否影响CPSR中条件标志位的值,有S时指令执行后的结果影响CPSR中条件标志位N和Z的值。
02 在计算第2操作数时更新标志C,不影响V标志。
03 该指令通常用于将操作数1的特定位置位的操作。
03 EOR指令
格式:EOR{<cond>}{S} Rd, Rn, operand2
用法:将两个操作数按位进行逻辑异或运算,结果放到目标寄存器Rd中,相当于Rd = Rn EOR operand2,其中Rn是操作数1,是一个寄存器;operand2为操作数2,可以是一个寄存器、被移位的寄存器或一个立即数。
示例:
EOR R0, R0, #0xF ; 将低4位取反,其余位不变(低4位和1异或,其余位和0异或)
备注:
01 S选项决定了指令的操作是否影响CPSR中条件标志位的值,有S时指令执行后的结果影响CPSR中条件标志位N和Z的值。
02 在计算第2操作数时更新标志C,不影响V标志。
03 该指令通常用于反转操作数1中的某些位。
04 BIC指令
格式:BIC{<cond>}{S} Rd, Rn, operand2
用法:用于清除操作数Rn的某些位,结果放到目标寄存器Rd中,相当于Rd = Rn AND (!operand2),其中Rn是操作数1,是一个寄存器;operand2为操作数2,可以是一个寄存器、被移位的寄存器或一个立即数。
示例:
BIC R0, R0, #9 ; 将R0的第0位和第3位清零,其余位不变
备注:
01 S选项决定了指令的操作是否影响CPSR中条件标志位的值,有S时指令执行后的结果影响CPSR中条件标志位N和Z的值。
02 在计算第2操作数时更新标志C,不影响V标志。
03 这里的operand2可以看作一个32位的掩码,如果在掩码中设置了某一位,则清除Rn中相应的位。
3、比较指令
比较指令通常用于把一个寄存器与一个32位的值进行比较或测试。比较指令根据结果更新CPSR中的标志位,但不影响其他寄存器。
在设置标志位后,其他指令可以通过条件执行来改变程序的执行顺序。对于比较指令,不需要使用S后缀就可以改变标志位的值。比较指令包括:
CMP–比较指令
CMN–反值比较指令
TST–位测试指令
TEQ–相等测试指令
01 CMP指令
格式:CMP{条件} Rn, operand2
用法:CMP指令将寄存器Rn的内容和另一个操作数operand2进行比较,同时更新CPSR中条件标志位的值。
示例:
CMP R1, #10 ;将寄存器R1的值与10相减,并设置CPSR的标志位
ADDGT R0, R0, #5 ; 如果R1>10,则执行ADDGT指令,将R0加5
备注:
01 该指令实质上是进行一次减法运算,但是不存储结果,只改变条件标志位。
02 后面的指令可以根据条件标志位来决定是否执行。例如:当操作数Rn大于操作数operand2时,执行CMP指令后,则此后带有GT后缀的指令将可以执行。
02 CMN指令
格式:CMN{条件} Rn, operand2
用法:CMN指令用于把一个寄存器Rn的内容和另一个操作数operand2取反后进行比较,同时更新CPSR中条件标志位的值。
示例:
CMN R0, R1 ; 将寄存器R0的值与寄存器R1的值相加,并根据结果设置CPSR的标志位
CMN R0, #10 ; 将寄存器R0的值与立即数10相加,并根据结果设置CPSR的标志位
CMN R0, #1 ; R0+1后判断是不是为1的补码,若是,则CPSR寄存器的Z置位(另一种说法)
备注:
01 该指令实质上是将操作数Rn和操作数operand2相加,并根据结果更改条件标志位。
02 后面的指令可以根据条件标志位来决定是否执行。
03 CMN指令和ADDS指令的区别在于CMN指令不保存运算结果,CMN指令可以用于负数的比较,比如例子中的第三个指令,表示R0和-1(1的补码)进行比较,若R0=-1,则Z置位,否则Z复位。
03 TST指令
格式:TST{条件} Rn, operand2
用法:用于把一个寄存器Rn的内容和另一个操作数operand2进行与运算,并根据运算结果更新CPSR中条件标志位的值。
示例:
TST R0, #3 ; 检查R0中的第0位和第1位是否为1,是则不应改变R0的值
TST R0, #0x0f ; 判断R0的低4位是否全为0
备注:
01 该指令通常用来检查是否设置了特定的位。
02 其中操作数Rn是要测试的数据,这里操作数operand2可以看作一个32位的掩码,如果在掩码中设置了某一位,表示检查该位。未设置的掩码位则表示不检查。
03 指令TST和ANDS的指令区别在于TST指令不保存运算结果,TST指令通常与EQ,NE条件配合使用,当所有测试位都为0的时候,EQ有效,而只要有一个测试位不为0,则NE有效。
04 TEQ指令
格式:TEQ{条件} Rn, operand2
用法:用于把一个寄存器Rn的内容和另一个操作数operand2按位进行异或运算,并根据运算结果更新CPSR中条件标志位的值。
示例:
TEQ R1, R2 ; 将寄存器R1的值与寄存器R2的值按位异或,并根据结果设置CPSR的标志位
备注:
01 该指令通常用于比较操作数Rn和操作数operand2是否相等。
02 指令TEQ和EORS的指令区别在于TEQ不保存运算结果,使用TEQ进行相等测试,常与EQ、NE条件配合使用,当两个数据相等时,EQ有效,否则NE。