需要注意的是 ,在SUBS 指令中,如果发生了借位操作 ,CPSR 寄存器中的 C 标志位设置成 0:如果没有发生借位操作,CPSR 寄存器中的 C 标志位设置成1。这与ADDS 指令中的进位指令正好相反 。这主要是为了适应 SBC 等指令的操作需要。
SBC 带位减法指令:
SBC 指令从寄存器<Rn>中减去<shifter_operand>表示的数值,再减去寄存器CPSR 中C 条件标志位的反码 ,并把结果保存到目标寄存器< Rd>中 ,同时根据操作的结果更新 CPSR 中相应的条件标志位。
《ARM体系结构与编程》杜春雷 P67
这个地方怎么理解??反向设置再取反码不是扯淡吗?
我认为是这样的,上边红色字体的这句话表述不准确,SUB本身是做减法,靠的是补码,也就是补(补<Rn> + 补<shifter_operand> + X),这个X就代表是否借位。
假设发生了借位,这时候C标注位为0,则对0取反,得到的是0xFFFF(假设是16位操作系统,就是16个1),而0xFFFF刚好是-1的补码,所以X也就是0xFFFF,也就是说在发生借位的情况下,在十进制的世界发生的实际上就是“减一”,符合需求。
相应的,如果没有借位,对1取反,的到0x0000,正好是-0的补码,符合需求。
===以下继续引用:
SBC 指令和 SUBS 指令联合使用可以实现两个 64 位的操作数相减 。如果寄存器RO 和 R I 中放置’一个 64 位的源操作数,其中 RO 中放置低32 位数值:寄存器R2 和R3 中放置另一个 64 位的源操作数,其中 R2 中放置低32 位数值。下面的指令序列实现了两个64 位操作数的减法操作 。
SUBS R4 , R0 , R2 SBC R5, Rl , R3
需要注意的是 ,在SBCS 指令中,如果发生了借位操作,CPSR 寄存器中的 C 标志位设置成 0:如果没有发生借位操作,CPSR 寄存器中的 C 标志位设置成1。这与ADDS 指令中的进位指令正好相反 。
以上理解,请指正!