Reputation: 51
Let's say I have an initial flag condition of z=0, n=0,c=1, q=0,v=0;
and the following registers r1=1000 0003 H r2=1000 0004 H
and have the following instruction: ADCS r1,r2
Would the r1 be 2000 0007 H with the new updated carry set which is zero or 2000 0008 H with the carry from the initial condition?
Upvotes: 0
Views: 142
Reputation: 71516
Think about the purpose of an add with carry. It is to cascade addition
So if the logic has 32 bit registers I can add 64, 96, etc all the way up to however much storage I have and care to use
A simple add
0
0011
+ 0111
=======
fill it in
01110
0011
+ 0111
=======
1010
So the result is 1010 with a carry out of 0
Now that could be visualized with an add and and adc
x 110
00 11
+ 01 11
==== ===
10
x is normally 0 for an ADD. But for ADC the carry out flag which comes from the carry out of a prior operation is used as the carry in.
011 110
00 11
+ 01 11
==== ===
10 10
The add on the right 10 with a carry out of 1, and the left uses that carry in.
The result is still 1010 with a carry out of 0.
This scales up to whatever number of bits in your registers or alu.
ADC means the carry flag is used as the carry in for the addition.
Subtract with borrow is slightly more complicated as some architectures invert the carry out and you need to invert the carry in, but still you can do the same math as above and see subtract with borrow uses the carry flag just like add with carry.
So
z=0, n=0,c=1, q=0,v=0;
1000 0003 H r2=1000 0004
1
00010000000000000000000000000011
+ 00010000000000000000000000000100
======================================
and you can easily fill that in.
Upvotes: 1
Reputation: 57922
The old value of the carry flag is included in the addition, and it is set afterwards to indicate whether the new addition caused a carry. Following your example code, r1 will equal 20000008H
and the carry flag will be zero.
The main point of an add-carry instruction is to be used in a loop to add multiple-precision integers one word at a time, propagating the carry through. So it can't really work any other way than this.
In general, for such questions, if a test is not enough to convince you, then refer to the ARM Architecture Reference Manual. They have detailed pseudocode for every instruction that defines precisely what it does. For this instruction they have
(result, nzcv) = AddWithCarry(R[n], shifted, PSTATE.C);
// ... irrelevant other stuff
PSTATE.<N,Z,C,V> = nzcv;
showing clearly that the value of the carry flag is used before being updated.
Upvotes: 1