Why does the flags in ARM are not affected if there a change in the Register?

167 Views Asked by At

So I have this problem where

ANDS  R1, R2, R3 

and to assume the flags are initially N=0 Z=0 C=0 V=1 Q=0

R1: 0000C5BF H 
R2: 0000A0F9 H 
R3: is 00000000 H

I have to examine the end results of the register and say whether the flags are affected,

so from calculating, the answer becomes: R1 is 00000000H . Since the value is zero, Z=1 , , my question since there is no overflow either to R1, why does V still stay 1, why does it not change to zero.

I am not using any ARM software to do this, so I need help understanding how the flags work in ARM.

2

There are 2 best solutions below

5
Jake 'Alquimista' LEE On

You should read the manual carefully: ands instruction doesn't affect the v flag. Which means: It remains the way it has been prior to the instrucion's execution.

3
Nate Eldredge On

The V flag (oVerflow) is used by addition and subtraction instructions to indicate a signed overflow; e.g. the result of the instruction does not equal the mathematical result when the operands are interpreted as signed integers. This has no relevance to a bitwise logic instruction like AND, so there's nothing meaningful that ANDS could do with the V flag. Therefore, the ARM32 architecture specifies that it is left unchanged.

You might think we could make the same argument for the C flag (Carry), which also has no obvious meaning for a bitwise logic instruction. But keep in mind, ARM has a barrel shifter. We are allowed to do things like ANDS R1, R2, R3, LSL #5 to perform R1 = R2 & (R3 << 5). Then the carry is set based on the result of the shift, being the least significant bit shifted out (in this example, bit 27 of R3, if I am counting correctly). The other shift types manipulate the carry in other ways which the ARM spec describes.

So ANDS R1, R2, R3 is presumably an alias for ANDS R1, R2, R3, LSL #0 or something like that. That would cause the carry flag to be cleared, since no bit is shifted out.

Note that ARM64 dropped this behavior, probably because it causes difficulties for out-of-order execution with register renaming when an instruction modifies part of a register (here NCZV) and leaves other parts unchanged: either the parts have to be renamed separately, or the instruction gains an unwanted read dependency on the NZCV register. So on ARM64, ANDS just unconditionally zeros the V and C flags.