Hi,
I find C code not executing in the desired way. Then I step in assembly code of Tiva-C M4F core. Below is the disassembly code:
$C$L5: nop
0000033a: 280A CMP R0, #10
0000033c: D3C9 BCC $C$L5
here_label:
R0 is '0'. It is found that after BCC exec, the core goes $C$L5, not goes to here_label.
In xPSR, 'C' is '0'. I want to know BCC in detail, but the found description online is ambiguous to me. Especially the last column comments on Arithmetic. Could you explain the disassembly code running when flag 'C'=0, it goes to $C$L5, not here_label?
Thanks,
Hello ruwan2,according to ARMv7M ARMARM, the operation of
"CMP<c><q> <Rn>, #<const>"
is
if ConditionPassed() thenEncodingSpecificOperations();(result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');APSR.N = result<31>;APSR.Z = IsZeroBit(result);APSR.C = carry;APSR.V = overflow;
In your case, the operation is0x00000000+0xFFFFFFF5+0x00000001=0xFFFFFFF6.This does not cause the carry.So BCC instruction is taken.
In other words, the operation is "0-10 = -9",This causes not the carry but the borrow.The carry is complement (or inversion) of the borrow.So, if the borrow is '1', then the carry is '0'.
Best regards,Yasuhiko Koumoto.
Normally, an assembly-programmer would not use BCC and BCS with CMP.
This is because the carry flag operates in the oposite way on ARM than on most other architectures.
The BCC and BCS still works the same way as on other architectures, but the CMP does not generate a carry when the first operand is less than the second operand for instance; instead it starts by setting the carry flag and uses it as a 32th bit on subtraction (and thus also CMP, because CMP is in fact a SUBS where the result is thrown away).
CC means Carry Clear (C=0, borrow)
CS means Carry Set (C=1, no borrow)
See this great 4-part article by Jacob Bramley.
> This is because the carry flag operates in the oposite way on ARM than on most other architectures.
This statement applies to subtraction and instruction that uses subtraction to accomplish an operation.
Just to avoid misinterpretation.
Just a minor correction,
0 - 10 = -10
which is also equivalent to (NOT 9), the (one's) complement of 9.
-10 = 0xFFFFFFF6 = NOT 9
From Jens Bauer's reply:
> Normally, an assembly-programmer would not use BCC and BCS with CMP.
What causes confusion is this:
the condition that the CMP and the succeeding conditional branch evaluates is if R0 is (unsigned) lower than 10.
Unfortunately, the disassembler would not know, or would not want to know , about the context and it opted to disassemble to BCC. It could have been easier for you to analyze the code if BLO, instead of BCC, was chosen in the disassembly.
Yes, that's correct. Sorry for the confusion.
Hello goodwin,
I am sorry for the mistake and thank you for your correction.
Best regards,
Yasuhiko Koumoto.