在汇编中,当他们说“立即数据”是签名或未签名的时候?
我正在写一个Gameboy模拟器并在这里使用操作码:
http://www.pastraiser.com/cpu/gameboy/gameboy_opcodes.html
操作码0xC6例如是ADD A,d8。
我的猜测是,它是未签名的,为什么他们需要“SUB A,d8”但我想我在检查我的代码时会问...
答案 0 :(得分:6)
在双人称赞系统中,签名或签名无关紧要。
执行比较指令时会发生值(和溢出)的解释。在那之前它只是位。将0x8000添加到0x0001会给出0x8001,无论其中任何一个值是有符号还是无符号。
您应该查看ADD和SUB的操作码。可能实际上没有两种不同的操作。可能是SUB只是否定操作数,然后发出ADD指令。
答案 1 :(得分:3)
我已经写了一篇回复说,当我注意到这可能并不完全准确时,Gameboy的CPU(看起来基于Z-80)上的即时数据已经签名了,我发现这可能并不完全准确:
假设这个CPU,因为似乎没有用于有符号和无符号操作数的单独操作码,实际上并不区分有符号和无符号值。这意味着负数只是使用二进制补码形式编码。使用该表单,加法运算对有符号或无符号数字的工作方式完全相同; CPU根本不在乎。
但是,在解释结果时,您会关心。如果上述假设是正确的,则意味着您可以根据需要解释8位加法的结果,因为对于有符号或无符号数据,加法运算完全相同。
如果您添加了两个您认为无符号的值,则结果将位于0-255范围内。
如果您添加了两个您认为已签名的值(并且负数以二进制补码形式编码),则结果将位于-128-127范围内。
答案 2 :(得分:3)
好像它是一个unsigned int。看看MAME的LR35902 CPU模拟器,他们立即使用UINT8。
一些相关代码:
/* ... */
case 0xC6: /* ADD A,n8 */
x = mem_ReadByte (cpustate, cpustate->w.PC++);
ADD_A_X (x)
break;
/* ... */
#define ADD_A_X(x) \
{ \
register UINT16 r1,r2; \
register UINT8 f; \
r1=(UINT16)((cpustate->b.A&0xF)+((x)&0xF)); \
r2=(UINT16)(cpustate->b.A+(x)); \
cpustate->b.A=(UINT8)r2; \
if( ((UINT8)r2)==0 ) f=FLAG_Z; \
else f=0; \
if( r2>0xFF ) f|=FLAG_C; \
if( r1>0xF ) f|=FLAG_H; \
cpustate->b.F=f; \
}
现在,LD HL,SP+n8
的例程是
case 0xF8: /* LD HL,SP+n8 */
/*
* n = one UINT8 signed immediate value.
*/
{
register INT32 n;
n = (INT32) ((INT8) mem_ReadByte (cpustate, cpustate->w.PC++));
这里立即转换为带符号的8位int (INT8)
,所以我想它是无符号的。