2014-02-07 39 views
6

考虑到这一点的示例代码:Z80注册字节序

ZilogZ80A cpu = new ZilogZ80A(); 
cpu.GeneralRegisters.H.FromUInt(229); 
cpu.GeneralRegisters.L.FromUInt(90); 
Console.WriteLine("H : " + cpu.GeneralRegisters.H.ToString()); 
Console.WriteLine("L : " + cpu.GeneralRegisters.L.ToString()); 
Console.WriteLine("HL: " + cpu.GeneralRegisters.HL.ToString()); 

Console.WriteLine("Load 23268 (0x5AE4) into register HL..."); 
cpu.GeneralRegisters.HL.FromUInt(23268); 

Console.WriteLine("H : " + cpu.GeneralRegisters.H.ToString()); 
Console.WriteLine("L : " + cpu.GeneralRegisters.L.ToString()); 
Console.WriteLine("HL: " + cpu.GeneralRegisters.HL.ToString()); 

其为执行以下操作:

  • 负载229(十进制)到寄存器H
  • 负载90(十进制)到寄存器L
  • 打印出H,L和HL寄存器的值(十六进制,二进制MSB,十进制)
  • 加载23268(十进制)int o寄存器HL
  • 再次打印出H,L和HL寄存器的值。

输出示例:

H : 08-bit length register (@45653674): 0x00E5 | MSB 0b11100101 | 229 
L : 08-bit length register (@41149443): 0x005A | MSB 0b01011010 | 90 
HL: 16-bit length register (@39785641): 0x5AE5 | MSB 0b01011010 11100101 | 23269 
Load 23268 (0x5AE4 into register HL... 
H : 08-bit length register (@45653674): 0x00E4 | MSB 0b11100100 | 228 
L : 08-bit length register (@41149443): 0x005A | MSB 0b01011010 | 90 
HL: 16-bit length register (@39785641): 0x5AE4 | MSB 0b01011010 11100100 | 23268 

现在的问题:

  1. 是上述假设(和样品输出)寄存器如何运作是否正确?
  2. 其他寄存器对(AF,BC,DE)的功能是否完全相同?
  3. 如果对1.和2.的答案是肯定的,为什么Z80会考虑小端?当HL寄存器的内容写入存储器时,L字节先行,但(当它们按顺序读取时,字节一定是大端顺序的)?
+3

endianess适用于在RAM中的排序。它不适用于加载了即时值的寄存器。如果你正在将'0x5AE5'写入RAM中,那么endianess会确定它是否以5AE5或E55A的形式进入。 –

回答

9

是 - HL由H作为最高有效字节组成,L最小。如果您执行像ADD HL,BC这样的16位操作,则从L+C的最高位进位将进入H+B的计算。所有的寄存器对在这方面都相似。

这是因为写入的逻辑顺序与endianess无关。例如。在C中,您不必在某些平台上编写0x0001,而在其他平台上编写0x0100。写作时,首先写出最重要的。

z80是小端,因为如果您要将HL存储到内存中,L将在H之前写入一个字节。如果您要阅读,L将从H之前的地址读取。

+0

谢谢!但为什么我感到困惑的是,如果你先将L(5A)写入内存(例如mem位置1000),然后再将H(E5)写入内存。位置1001),当顺序读取时(5AE5),仍然看起来“相同”排列。或者上面的示例输出有问题吗? – ChristopheD

+1

我并不完全理解这个问题,但是:如果将HL写入内存,那么Z80将写入L,然后写入H.如果模拟器将HL放在屏幕上供人类使用,它将打印H然后L,因为它知道您正在输出一个16位的数量,这就是他们写的。相反,如果您将'5A'后面跟着'E5'存储到内存然后输出内存给一个人,它将逐字节地打印,因为这就是写入内存的方式。如果你从该地址读取HL,它将实际为L,然后为H,给出16位值“E55A”。 – Tommy

+0

输出错误的原因是因为它打印出寄存器的当前值,而不是寄存器的当前值*存储到存储器*。请参阅我的答案以获得不同的解释。 – James

3
ld hl, $1234 
ld ($fc00), hl 

此时,H = $ 12,L = $ 34,如您的代码所示。 $ fc00 = $ 34的字节,$ fc01 = $ 12的字节。 所以,如果你做后续:

ld hl, $5678 
ld ($fc02), hl 

($ FC00)= $ 34($ FC01)= $ 12($ FC02)= $ 78,以及($ FC03)= $ 56因此,从$ fc00逐字节读取,内存将是$ 34127856,而不是 $ 12345678,因为Z80是小端。