Math Z80上的溢出和携带标志

Math Z80上的溢出和携带标志,math,assembly,z80,carryflag,signed-overflow,Math,Assembly,Z80,Carryflag,Signed Overflow,我已经开始在我的Z80内核上实现adda,r操作码集。关于进位和溢出标志,我有点困惑,我想我已经钉好了,但我想把它交给社区来检查我是否正确 基本上,从我所看到的,Z80中的ALU不关心有符号/无符号操作,它只是添加位。这意味着,如果两个8位值相加,并且由于相加而产生9位值,则将设置进位标志。这包括添加两个负数2的补码,例如-20(11101100)和-40(11011000),因为虽然结果是-60(11000100),但结果实际上是9位值1100 0100。这当然意味着,如果加上两个负数2的补码

我已经开始在我的Z80内核上实现adda,r操作码集。关于进位和溢出标志,我有点困惑,我想我已经钉好了,但我想把它交给社区来检查我是否正确

基本上,从我所看到的,Z80中的ALU不关心有符号/无符号操作,它只是添加位。这意味着,如果两个8位值相加,并且由于相加而产生9位值,则将设置进位标志。这包括添加两个负数2的补码,例如-20(11101100)和-40(11011000),因为虽然结果是-60(11000100),但结果实际上是9位值1100 0100。这当然意味着,如果加上两个负数2的补码值,即使没有溢出条件,进位标志也会被设置,对吗

其次,我决定检测这条指令中的溢出,我将对两个操作数的第7位进行异或运算,如果结果是10000000,那么肯定没有溢出-如果结果是00000000,那么可能会有溢出,因为符号相同,因此,我将加法结果的第7位与任一操作数的第7位进行异或运算,如果结果为10000000,则发生溢出,我设置了P/V溢出标志。我也在这里吗


很抱歉问了这么一个复杂的问题,我很确定我是对的,但在我继续基于这个逻辑的无数指令之前,我需要知道。非常感谢。

结果的位来自无符号整数的截断和。add指令不关心这里的符号,也不关心您自己对整数的解释,即有符号或无符号。它只是把数字加起来,就好像没有签名一样

进位标志(减法时为借位)是8位无符号整数相加后不存在的第9位。实际上,此标志表示无符号整数的add/sub的溢出/下溢。再说一遍,add根本不关心这里的符号,它只是添加数字,就好像数字没有符号一样

添加两个负2的补码将导致进位标志设置为1,正确

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

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

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

So overflow flag=执行从第6位到第7位的异或进位标志

我和你计算溢出标志的方法都是正确的。事实上,“Z80状态指示器标志”一节中描述了这两种情况

以下是在C语言中模拟大多数ADC指令的方法,在C语言中,您无法直接访问CPU的标志,也无法充分利用模拟CPU的ADC指令:

#包括
#包括
#如果字符位!=8.
#错误字符应该正好有8位。
#恩迪夫
typedef无符号字符uint8;
typedef签名字符int8;
#定义标志\u CY\u移位0
#定义标志\u OV\u移位1
#定义标志\u CY\u掩码(1 0xFF-b)。
//
//进位=1:进位=1 IFF(a+b+1>0xFF)或,
//等效地,(a+b>=0xFF)或,
//等价地,但避免了C中的溢出:(a>=0xFF-b)。
//
//还要计算和位。
if(*标志和标志屏蔽)
{
执行=(a>=0xFF-b);
*acc=a+b+1;
}
其他的
{
结转=(a>0xFF-b);
*acc=a+b;
}
#如果0
//通过符号比较计算溢出。
进位=((a^b)^0x80)和0x80;
if(carryIns)//如果加数符号相同
{
//如果和号与任意一个加数的符号不同,则溢出
进位=(*acc^a)&0x80)!=0;
}
#否则
//计算所有进位。
//记住,总和的每一位=
//加数a的位异或加数b的位异或进位,
//我们可以算出a,b的所有进位和它们的和。
结转=*acc^a^b;
//使用进位和进位计算溢出量
//最重要的进项。
结转=(结转>>7)^结转;
#恩迪夫
//更新标志。
*flags&=~(flags_CY_MASK | flags_OV_MASK);

*flags |=(carrout另一种可能更容易理解的方法。执行求和时:

  • 符号始终设置为结果的第7位
  • 如果结果为0x00,则设置0
  • 半进位在操作数的右半字节和溢出时设置
  • 溢出在两个有符号操作数均为正且有符号和均为负或两个有符号操作数均为负且有符号和均为正时设置
  • 添加/删除已重置
  • 如果无符号和溢出0xFF,则设置进位

这太完美了-非常感谢:-)我知道我的思路是对的。还感谢您的代码示例。我实际上使用的是Java(因为我的目标是在它完成后成为一个完全跨平台的主系统仿真器),尽管我能理解足够多的C语言来了解abo上的内容
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