在我的 Raspberry PI 上学习 ARM 汇编时,我一直在摆弄 Flags。我设计了仅设置零标志、仅设置负数和仅设置进位标志的方法。但是我想不出一种方法来仅设置溢出标志。是否可以?任何帮助将不胜感激!
挑战是不要写信给cpsr(因为出于各种原因我不允许这样做,否则这将是最好的解决方案,因为它是最好的解决方案)
编辑:仅设置溢出标志,其他所有标志为零/清除。仅使用算术或移位。 NZCV = 0001
Edit2:为了进一步澄清,我认为需要多个指令才能实现这一点。
我没有看到仅使用一条指令的明显方法,但您可以组合使用。例如:
mov r0, #0x80000000
mov r1, #0x00000001
subs r2, r0, r1 ; C and V set
mov r3, #0x10
asrs r3, #1 ; C cleared, V not changed
我对汇编比较陌生,在实验和研究时我发现了以下设置单个标志的方法。请注意,我使用的是基于 ARM7TDMI-S 的 32 位 RISC 微控制器架构。有所谓的 MRS 和 MSR 指令。 MRS 用于读取标志,MSR 用于写入标志。
这是我设置每个标志的方法:
msr cpsr_cxsf, #0x80000000 ; N Flag
msr cpsr_cxsf, #0x40000000 ; Z flag
msr cpsr_cxsf, #0x20000000 ; C Flag
msr cpsr_cxsf, #0x10000000 ; V Flag
abc cr
000 00
001 01 x
010 01
011 10
100 01
101 10
110 10 x
111 11
有符号溢出是指进位不等于进位。如果第一列是操作数 a b 的 msbits 并进位到 msbit(其他位与有符号或无符号溢出无关),则右列被进位,并且结果。如果结果为 1,则得到 N 位。所以操作数的 msbit 必须为 1,进位必须为 0
0xxx (carrys)
1xxx (operand a)
1xxx (operand b)
0x80 + 0x80 = 0x00 (zero flag)
0x81 + 0x81 = 0x02 (need some other ones)
100000010
10000001
+ 10000001
============
00000010
-127 + -127 = -254 你能得到的最大负数是-128, 0x80,所以这是一个有符号溢出。
但是有一个执行,不是吗?
所以也许减法会起作用 -127 - 127
100000011
10000001
+ 10000000
============
00000010
但是作为减法,它是否会将进位反转为借位,从而在进位位中留下 0?这不是 ARM 的工作方式,其他处理器/内核会这样做。
因此,为了能够做到这一点,您需要一个处理器将进位定义为减法的借位(在加法末尾反转进位)。
您在撰写本文时编辑了您的问题,移位操作将如何修改带符号的溢出?需要加减(需要使用加法器)。