/ 猿问

# Z80上的溢出和进位标志

2019-12-03 16:23:57

## 3 回答

#include <stdio.h>

#include <limits.h>

#if CHAR_BIT != 8

#error char expected to have exactly 8 bits.

#endif

typedef unsigned char uint8;

typedef signed char int8;

#define FLAGS_CY_SHIFT 0

#define FLAGS_OV_SHIFT 1

void Adc(uint8* acc, uint8 b, uint8* flags)

{

uint8 a = *acc;

uint8 carryIns;

uint8 carryOut;

// Calculate the carry-out depending on the carry-in and addends.

//

// carry-in = 0: carry-out = 1 IFF (a + b > 0xFF) or,

//   equivalently, but avoiding overflow in C: (a > 0xFF - b).

//

// carry-in = 1: carry-out = 1 IFF (a + b + 1 > 0xFF) or,

//   equivalently, (a + b >= 0xFF) or,

//   equivalently, but avoiding overflow in C: (a >= 0xFF - b).

//

// Also calculate the sum bits.

{

carryOut = (a >= 0xFF - b);

*acc = a + b + 1;

}

else

{

carryOut = (a > 0xFF - b);

*acc = a + b;

}

#if 0

// Calculate the overflow by sign comparison.

carryIns = ((a ^ b) ^ 0x80) & 0x80;

if (carryIns) // if addend signs are the same

{

// overflow if the sum sign differs from the sign of either of addends

carryIns = ((*acc ^ a) & 0x80) != 0;

}

#else

// Calculate all carry-ins.

// Remembering that each bit of the sum =

// we can work out all carry-ins from a, b and their sum.

carryIns = *acc ^ a ^ b;

// Calculate the overflow using the carry-out and

// most significant carry-in.

carryIns = (carryIns >> 7) ^ carryOut;

#endif

// Update flags.

*flags |= (carryOut << FLAGS_CY_SHIFT) | (carryIns << FLAGS_OV_SHIFT);

}

void Sbb(uint8* acc, uint8 b, uint8* flags)

{

// a - b - c = a + ~b + 1 - c = a + ~b + !c

}

const uint8 testData[] =

{

0,

1,

0x7F,

0x80,

0x81,

0xFF

};

int main(void)

{

unsigned aidx, bidx, c;

for (c = 0; c <= 1; c++)

for (aidx = 0; aidx < sizeof(testData)/sizeof(testData[0]); aidx++)

for (bidx = 0; bidx < sizeof(testData)/sizeof(testData[0]); bidx++)

{

uint8 a = testData[aidx];

uint8 b = testData[bidx];

uint8 flags = c << FLAGS_CY_SHIFT;

printf("%3d(%4d) + %3d(%4d) + %u = ",

a, (int8)a, b, (int8)b, c);

printf("%3d(%4d) CY=%d OV=%d\n",

a, (int8)a, (flags & FLAGS_CY_MASK) != 0, (flags & FLAGS_OV_MASK) != 0);

}

printf("SBB:\n");

for (c = 0; c <= 1; c++)

for (aidx = 0; aidx < sizeof(testData)/sizeof(testData[0]); aidx++)

for (bidx = 0; bidx < sizeof(testData)/sizeof(testData[0]); bidx++)

{

uint8 a = testData[aidx];

uint8 b = testData[bidx];

uint8 flags = c << FLAGS_CY_SHIFT;

printf("%3d(%4d) - %3d(%4d) - %u = ",

a, (int8)a, b, (int8)b, c);

Sbb(&a, b, &flags);

printf("%3d(%4d) CY=%d OV=%d\n",

a, (int8)a, (flags & FLAGS_CY_MASK) != 0, (flags & FLAGS_OV_MASK) != 0);

}

return 0;

}

0(   0) +   0(   0) + 0 =   0(   0) CY=0 OV=0

0(   0) +   1(   1) + 0 =   1(   1) CY=0 OV=0

0(   0) + 127( 127) + 0 = 127( 127) CY=0 OV=0

0(   0) + 128(-128) + 0 = 128(-128) CY=0 OV=0

0(   0) + 129(-127) + 0 = 129(-127) CY=0 OV=0

0(   0) + 255(  -1) + 0 = 255(  -1) CY=0 OV=0

1(   1) +   0(   0) + 0 =   1(   1) CY=0 OV=0

1(   1) +   1(   1) + 0 =   2(   2) CY=0 OV=0

1(   1) + 127( 127) + 0 = 128(-128) CY=0 OV=1

1(   1) + 128(-128) + 0 = 129(-127) CY=0 OV=0

1(   1) + 129(-127) + 0 = 130(-126) CY=0 OV=0

1(   1) + 255(  -1) + 0 =   0(   0) CY=1 OV=0

127( 127) +   0(   0) + 0 = 127( 127) CY=0 OV=0

127( 127) +   1(   1) + 0 = 128(-128) CY=0 OV=1

127( 127) + 127( 127) + 0 = 254(  -2) CY=0 OV=1

127( 127) + 128(-128) + 0 = 255(  -1) CY=0 OV=0

127( 127) + 129(-127) + 0 =   0(   0) CY=1 OV=0

127( 127) + 255(  -1) + 0 = 126( 126) CY=1 OV=0

128(-128) +   0(   0) + 0 = 128(-128) CY=0 OV=0

128(-128) +   1(   1) + 0 = 129(-127) CY=0 OV=0

128(-128) + 127( 127) + 0 = 255(  -1) CY=0 OV=0

128(-128) + 128(-128) + 0 =   0(   0) CY=1 OV=1

128(-128) + 129(-127) + 0 =   1(   1) CY=1 OV=1

128(-128) + 255(  -1) + 0 = 127( 127) CY=1 OV=1

129(-127) +   0(   0) + 0 = 129(-127) CY=0 OV=0

129(-127) +   1(   1) + 0 = 130(-126) CY=0 OV=0

129(-127) + 127( 127) + 0 =   0(   0) CY=1 OV=0

129(-127) + 128(-128) + 0 =   1(   1) CY=1 OV=1

129(-127) + 129(-127) + 0 =   2(   2) CY=1 OV=1

129(-127) + 255(  -1) + 0 = 128(-128) CY=1 OV=0

255(  -1) +   0(   0) + 0 = 255(  -1) CY=0 OV=0

255(  -1) +   1(   1) + 0 =   0(   0) CY=1 OV=0

255(  -1) + 127( 127) + 0 = 126( 126) CY=1 OV=0

255(  -1) + 128(-128) + 0 = 127( 127) CY=1 OV=1

255(  -1) + 129(-127) + 0 = 128(-128) CY=1 OV=0

255(  -1) + 255(  -1) + 0 = 254(  -2) CY=1 OV=0

0(   0) +   0(   0) + 1 =   1(   1) CY=0 OV=0

0(   0) +   1(   1) + 1 =   2(   2) CY=0 OV=0

0(   0) + 127( 127) + 1 = 128(-128) CY=0 OV=1

0(   0) + 128(-128) + 1 = 129(-127) CY=0 OV=0

0(   0) + 129(-127) + 1 = 130(-126) CY=0 OV=0

0(   0) + 255(  -1) + 1 =   0(   0) CY=1 OV=0

1(   1) +   0(   0) + 1 =   2(   2) CY=0 OV=0

1(   1) +   1(   1) + 1 =   3(   3) CY=0 OV=0

1(   1) + 127( 127) + 1 = 129(-127) CY=0 OV=1

1(   1) + 128(-128) + 1 = 130(-126) CY=0 OV=0

1(   1) + 129(-127) + 1 = 131(-125) CY=0 OV=0

1(   1) + 255(  -1) + 1 =   1(   1) CY=1 OV=0

127( 127) +   0(   0) + 1 = 128(-128) CY=0 OV=1

127( 127) +   1(   1) + 1 = 129(-127) CY=0 OV=1

127( 127) + 127( 127) + 1 = 255(  -1) CY=0 OV=1

127( 127) + 128(-128) + 1 =   0(   0) CY=1 OV=0

127( 127) + 129(-127) + 1 =   1(   1) CY=1 OV=0

127( 127) + 255(  -1) + 1 = 127( 127) CY=1 OV=0

128(-128) +   0(   0) + 1 = 129(-127) CY=0 OV=0

128(-128) +   1(   1) + 1 = 130(-126) CY=0 OV=0

128(-128) + 127( 127) + 1 =   0(   0) CY=1 OV=0

128(-128) + 128(-128) + 1 =   1(   1) CY=1 OV=1

128(-128) + 129(-127) + 1 =   2(   2) CY=1 OV=1

128(-128) + 255(  -1) + 1 = 128(-128) CY=1 OV=0

129(-127) +   0(   0) + 1 = 130(-126) CY=0 OV=0

129(-127) +   1(   1) + 1 = 131(-125) CY=0 OV=0

129(-127) + 127( 127) + 1 =   1(   1) CY=1 OV=0

129(-127) + 128(-128) + 1 =   2(   2) CY=1 OV=1

129(-127) + 129(-127) + 1 =   3(   3) CY=1 OV=1

129(-127) + 255(  -1) + 1 = 129(-127) CY=1 OV=0

255(  -1) +   0(   0) + 1 =   0(   0) CY=1 OV=0

255(  -1) +   1(   1) + 1 =   1(   1) CY=1 OV=0

255(  -1) + 127( 127) + 1 = 127( 127) CY=1 OV=0

255(  -1) + 128(-128) + 1 = 128(-128) CY=1 OV=0

255(  -1) + 129(-127) + 1 = 129(-127) CY=1 OV=0

255(  -1) + 255(  -1) + 1 = 255(  -1) CY=1 OV=0

SBB:

0(   0) -   0(   0) - 0 =   0(   0) CY=0 OV=0

0(   0) -   1(   1) - 0 = 255(  -1) CY=1 OV=0

0(   0) - 127( 127) - 0 = 129(-127) CY=1 OV=0

0(   0) - 128(-128) - 0 = 128(-128) CY=1 OV=1

0(   0) - 129(-127) - 0 = 127( 127) CY=1 OV=0

0(   0) - 255(  -1) - 0 =   1(   1) CY=1 OV=0

1(   1) -   0(   0) - 0 =   1(   1) CY=0 OV=0

1(   1) -   1(   1) - 0 =   0(   0) CY=0 OV=0

1(   1) - 127( 127) - 0 = 130(-126) CY=1 OV=0

1(   1) - 128(-128) - 0 = 129(-127) CY=1 OV=1

1(   1) - 129(-127) - 0 = 128(-128) CY=1 OV=1

1(   1) - 255(  -1) - 0 =   2(   2) CY=1 OV=0

127( 127) -   0(   0) - 0 = 127( 127) CY=0 OV=0

127( 127) -   1(   1) - 0 = 126( 126) CY=0 OV=0

127( 127) - 127( 127) - 0 =   0(   0) CY=0 OV=0

127( 127) - 128(-128) - 0 = 255(  -1) CY=1 OV=1

127( 127) - 129(-127) - 0 = 254(  -2) CY=1 OV=1

127( 127) - 255(  -1) - 0 = 128(-128) CY=1 OV=1

128(-128) -   0(   0) - 0 = 128(-128) CY=0 OV=0

128(-128) -   1(   1) - 0 = 127( 127) CY=0 OV=1

128(-128) - 127( 127) - 0 =   1(   1) CY=0 OV=1

128(-128) - 128(-128) - 0 =   0(   0) CY=0 OV=0

128(-128) - 129(-127) - 0 = 255(  -1) CY=1 OV=0

128(-128) - 255(  -1) - 0 = 129(-127) CY=1 OV=0

129(-127) -   0(   0) - 0 = 129(-127) CY=0 OV=0

129(-127) -   1(   1) - 0 = 128(-128) CY=0 OV=0

129(-127) - 127( 127) - 0 =   2(   2) CY=0 OV=1

129(-127) - 128(-128) - 0 =   1(   1) CY=0 OV=0

129(-127) - 129(-127) - 0 =   0(   0) CY=0 OV=0

129(-127) - 255(  -1) - 0 = 130(-126) CY=1 OV=0

255(  -1) -   0(   0) - 0 = 255(  -1) CY=0 OV=0

255(  -1) -   1(   1) - 0 = 254(  -2) CY=0 OV=0

255(  -1) - 127( 127) - 0 = 128(-128) CY=0 OV=0

255(  -1) - 128(-128) - 0 = 127( 127) CY=0 OV=0

255(  -1) - 129(-127) - 0 = 126( 126) CY=0 OV=0

255(  -1) - 255(  -1) - 0 =   0(   0) CY=0 OV=0

0(   0) -   0(   0) - 1 = 255(  -1) CY=1 OV=0

0(   0) -   1(   1) - 1 = 254(  -2) CY=1 OV=0

0(   0) - 127( 127) - 1 = 128(-128) CY=1 OV=0

0(   0) - 128(-128) - 1 = 127( 127) CY=1 OV=0

0(   0) - 129(-127) - 1 = 126( 126) CY=1 OV=0

0(   0) - 255(  -1) - 1 =   0(   0) CY=1 OV=0

1(   1) -   0(   0) - 1 =   0(   0) CY=0 OV=0

1(   1) -   1(   1) - 1 = 255(  -1) CY=1 OV=0

1(   1) - 127( 127) - 1 = 129(-127) CY=1 OV=0

1(   1) - 128(-128) - 1 = 128(-128) CY=1 OV=1

1(   1) - 129(-127) - 1 = 127( 127) CY=1 OV=0

1(   1) - 255(  -1) - 1 =   1(   1) CY=1 OV=0

127( 127) -   0(   0) - 1 = 126( 126) CY=0 OV=0

127( 127) -   1(   1) - 1 = 125( 125) CY=0 OV=0

127( 127) - 127( 127) - 1 = 255(  -1) CY=1 OV=0

127( 127) - 128(-128) - 1 = 254(  -2) CY=1 OV=1

127( 127) - 129(-127) - 1 = 253(  -3) CY=1 OV=1

127( 127) - 255(  -1) - 1 = 127( 127) CY=1 OV=0

128(-128) -   0(   0) - 1 = 127( 127) CY=0 OV=1

128(-128) -   1(   1) - 1 = 126( 126) CY=0 OV=1

128(-128) - 127( 127) - 1 =   0(   0) CY=0 OV=1

128(-128) - 128(-128) - 1 = 255(  -1) CY=1 OV=0

128(-128) - 129(-127) - 1 = 254(  -2) CY=1 OV=0

128(-128) - 255(  -1) - 1 = 128(-128) CY=1 OV=0

129(-127) -   0(   0) - 1 = 128(-128) CY=0 OV=0

129(-127) -   1(   1) - 1 = 127( 127) CY=0 OV=1

129(-127) - 127( 127) - 1 =   1(   1) CY=0 OV=1

129(-127) - 128(-128) - 1 =   0(   0) CY=0 OV=0

129(-127) - 129(-127) - 1 = 255(  -1) CY=1 OV=0

129(-127) - 255(  -1) - 1 = 129(-127) CY=1 OV=0

255(  -1) -   0(   0) - 1 = 254(  -2) CY=0 OV=0

255(  -1) -   1(   1) - 1 = 253(  -3) CY=0 OV=0

255(  -1) - 127( 127) - 1 = 127( 127) CY=0 OV=1

255(  -1) - 128(-128) - 1 = 126( 126) CY=0 OV=0

255(  -1) - 129(-127) - 1 = 125( 125) CY=0 OV=0

255(  -1) - 255(  -1) - 1 = 255(  -1) CY=1 OV=0

• 符号始终设置为结果的第7位

• 如果结果为0x00，则设置为零

• 当操作数的右半字节和溢出时设置半进位

• 当两个操作数均为正且有符号和为负或两个操作数均为负且有符号和为正时，将设置溢出

• 添加/订阅被重置

• 如果无符号和溢出0xFF，则进位被设置

• 3 回答
• 0 关注
• 327 浏览

0/150