需要注意的是 ,在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 指令中的进位指令正好相反 。
以上理解,请指正!
以上转自: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的值是否和计算 结果高低位相同。