c语言溢出进位,Z80上的溢出和进位标志

从无符号整数的截断和中获得结果的位。add指令在这里既不关心符号,也不关心您自己对有符号或无符号整数的解释。它只是像数字未签名一样添加。

进位标志(或减法时借位)是8位无符号整数相加后的第9位。实际上,此标志表示无符号整数的加/减的上溢/下溢。再说一次,add根本不关心这里的符号,它只是像数字是未签名的那样添加。

将两个负2的补码相加会导致进位标记设置为1,正确。

溢出标志显示有符号整数的加/减是否存在上溢/下溢。要设置溢出标志,该指令将数字视为有符号(就像对于进位标志和结果的8位一样,将它们视为无符号)。

设置溢出标志的思想很简单。假设您将8位带符号整数符号扩展为9位,也就是说,只需将第7位复制到额外的第8位。如果这些9位带符号整数的9位和/差在位7和8中具有不同的值,则将发生上溢/下溢,这意味着加法/减法在第7位中丢失了结果的符号并将其用于结果的大小,换句话说,8位不能容纳符号位,因此幅度太大。

现在,当且仅当进位7的进位和进位8的进位(=从位7进位)不同时,结果的位7才可能与虚符号位8有所不同。那是因为我们从位7 =位8的加数开始,只有不同的进位可以以不同的方式影响结果。

因此,溢出标志=进位标志XOR从第6位进入第7位。

我和您的计算溢出标志的方法都是正确的。实际上,这两者都在《Z80 CPU用户手册》的“ Z80状态指示器标志”部分中进行了描述。

这是您可以在C语言中模拟大多数ADC指令的方法,其中您无法直接访问CPU的标志并且不能充分利用模拟CPU的ADC指令:

#include

#include

#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

#define FLAGS_CY_MASK  (1 << FLAGS_CY_SHIFT)

#define FLAGS_OV_MASK  (1 << FLAGS_OV_SHIFT)

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.

if (*flags & FLAGS_CY_MASK)

{

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 =

//   addend a's bit XOR addend b's bit XOR carry-in,

// 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 &= ~(FLAGS_CY_MASK | FLAGS_OV_MASK);

*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

*flags ^= FLAGS_CY_MASK;

Adc(acc, ~b, flags);

*flags ^= FLAGS_CY_MASK;

}

const uint8 testData[] =

{

0,

1,

0x7F,

0x80,

0x81,

0xFF

};

int main(void)

{

unsigned aidx, bidx, c;

printf("ADC:\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);

Adc(&a, b, &flags);

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;

}

输出:

ADC:

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

您可以更改#if 0为#if 1使用基于符号比较的方法进行溢出计算。结果将是相同的。乍一看,基于符号的方法也可以处理随身携带的情况,这有点令人惊讶。

请注意,通过使用将所有进位值计算half-carry到位0至7的方法,您还将免费获得DAA指令所需的标志值(从位3到位4)。

编辑:我添加了一个借位相减的功能(SBC / SBB指令),并得到了结果。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值