I'm an occasional C programmer. I've come across this bit of inline assembly code in a Turbo C program
#define ADC(dst,src) { asm MOV AX, dst; asm ADD AX, src; \
asm ADC AX, 0; asm MOV dst, AX; }
dst and src are both unsigned 16-bit integers.
It won't compile in GNU C++. Could someone please explain what it's doing? TIA!
The first two instructions add dst
and src
together, storing the result in the accumulator. The third instruction computes what's sometimes called the "end-around carry" and the fourth stores the result in dst
.
The following is an equivalent C implementation:
int32_t sum = dst + (int32_t)src;
dst = (int16_t)((sum & 0xffff) + (sum >> 16));
Wikipedia talks about end-around carry in its coverage of ones' complement:
To add two numbers represented in this system, one does a conventional binary addition, but it is then necessary to do an end-around carry: that is, add any resulting carry back into the resulting sum.
End-around carry is used, for example, when calculating IPv4 checksums.
A literal translation of this code to GNU C inline assembly is:
static inline short ADC(short dst, short src)
{
asm ("add %1, %0; adc $0, %0" : "+r"(dst) : "rmi"(src));
return (dst);
}
But the version provided by NPE should be a bit more portable.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With