ARM 指令集中,SBC 为什么C要取反

需要注意的是 ,在SUBS 指令中,如果发生了借位操作 ,CPSR 寄存器中的 标志位设置成 0:如果没有发生借位操作,CPSR 寄存器中的 标志位设置成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 位操作数的减法操作 。

扫描二维码关注公众号,回复: 9640544 查看本文章

SUBS R4 , R0 , R2 SBC  R5, Rl , R3

需要注意的是 ,在SBCS 指令中,如果发生了借位操作,CPSR 寄存器中的 C 标志位设置成 0:如果没有发生借位操作,CPSR 寄存器中的 C 标志位设置成1。这与ADDS 指令中的进位指令正好相反 。

以上理解,请指正!

以上转自:http://www.51hei.com/bbs/dpj-44558-1.html

--------------------------------------------

用ARM汇编实现64位数据的运算

R0和R1分别存放一个64位操作数的低32位和高32位,

R2和R3分别存放另一个64位操作数的低32位和高32位。

一、64位操作数的加法运算

ADDS R4,R0,R2

ADC R5,R1,R3

ADDS指令中,R4=R0+R2,且是否有进位会影响到CPSR寄存器中的C标志位;

ADC指令R5=R1+R3+C,这样,R4和R5就存放了64位和值的低32位和高32位。

二、64位操作数的减法运算

SUBS R4,R0,R2

SBC R5,R1,R3

SUBS指令中,R4=R0-R2,如果发生借位,则C=0【这和ADDS指令相反】;

SBC指令R5=R1-R3-C标志位的反码。

三、求64位操作数的负数

RSBS R2,R0,#0  ;R2=-R0,且发生了借位,则C标志位为0.

RSC R3,R1,#0   ;R3=-R1-C的反码【此处为1】

来自:http://blog.sina.com.cn/s/blog_6238e8790100nx7h.html

--------------------------------------------------

以下为自己的练习

main.c

#include<stdio.h>
#include<stdlib.h>
#include<stdint.h>

extern void asm_64bit_add(int a_low, int a_hig, int b_low, int b_hig);

int main(int argc, char* argv[]){
	int a = 3;
	int b = 2;
	int64_t a64 = 0xFEDCBA9876543211;
	int64_t b64 = 0x987654321FEDCBA;
	int64_t c64 = a64 + b64;

	int a_low = a64  & 0xFFFFFFFF;
	int a_hig = (a64 >> 32)  & 0xFFFFFFFF;

	int b_low = b64  & 0xFFFFFFFF;
	int b_hig = (b64 >> 32)  & 0xFFFFFFFF;
	int result =  0;
	printf("c64=0x%llx\n", c64);

	asm_64bit_add(a_low, a_hig, b_low, b_hig);


	return 0;
}

calc.S


 AREA  CALC, CODE, READONLY


  EXPORT asm_64bit_add



year EQU 2018

 GBLS Hello
Hello SETS "Hello, ""xiaoqiang"" !"

asm_64bit_add PROC
 ADDS R4, R0, R2
 ADC R5, R1, R3
 BX LR

 ENDP


  END

calc.S里只是进行了64 位运算,并未将R4\R5 拼合成数值,还不会。。。不过可以debug 查看 R4和R5的值是否和计算 结果高低位相同。

发布了106 篇原创文章 · 获赞 204 · 访问量 128万+

猜你喜欢

转载自blog.csdn.net/ab6326795/article/details/90269505