大会中的“即时数据”

时间:2010-08-08 14:24:04

标签: assembly

在汇编中,当他们说“立即数据”是签名或未签名的时候?

我正在写一个Gameboy模拟器并在这里使用操作码:

http://www.pastraiser.com/cpu/gameboy/gameboy_opcodes.html

操作码0xC6例如是ADD A,d8。

我的猜测是,它是未签名的,为什么他们需要“SUB A,d8”但我想我在检查我的代码时会问...

3 个答案:

答案 0 :(得分:6)

在双人称赞系统中,签名或签名无关紧要。

执行比较指令时会发生值(和溢出)的解释。在那之前它只是位。将0x8000添加到0x0001会给出0x8001,无论其中任何一个值是有符号还是无符号。

您应该查看ADD和SUB的操作码。可能实际上没有两种不同的操作。可能是SUB只是否定操作数,然后发出ADD指令。

答案 1 :(得分:3)

我已经写了一篇回复说,当我注意到这可能并不完全准确时,Gameboy的CPU(看起来基于Z-80)上的即时数据已经签名了,我发现这可能并不完全准确:

假设这个CPU,因为似乎没有用于有符号和无符号操作数的单独操作码,实际上并不区分有符号和无符号值。这意味着负数只是使用二进制补码形式编码。使用该表单,加法运算对有符号或无符号数字的工作方式完全相同; CPU根本不在乎。

但是,在解释结果时,您会关心。如果上述假设是正确的,则意味着您可以根据需要解释8位加法的结果,因为对于有符号或无符号数据,加法运算完全相同。

  • 如果您添加了两个您认为无符号的值,则结果将位于0-255范围内。

  • 如果您添加了两个您认为已签名的值(并且负数以二进制补码形式编码),则结果将位于-128-127范围内。

参见例如this page on Z-80 assembler

答案 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),所以我想它是无符号的。