Z80注册字节序

Chr*_*heD 6 z80 endianness cpu-registers

考虑此示例代码:

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());
Run Code Online (Sandbox Code Playgroud)

这是做什么的:

  • 将229(十进制)加载到寄存器H中
  • 将90(十进制)加载到寄存器L中
  • 打印H,L和HL寄存器的值(十六进制,二进制MSB,十进制)
  • 将23268(十进制)加载到寄存器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
Run Code Online (Sandbox Code Playgroud)

现在提问:

  1. 上述关于寄存器功能如何正确的假设(和样本输出)是什么?
  2. 其他寄存器对(AF,BC,DE)的功能是否完全相同?
  3. 如果对1.和2.的答案是肯定的,为什么Z80会被认为是小端?当HL寄存器的内容被写入存储器时,L字节首先出现,但是(之后顺序读取它们的字节肯定是大端序)?

Tom*_*mmy 9

是 - HL由H作为最重要的字节,L作为最小.如果你执行一个16位的操作,ADD HL,BC那么从最高位L+C进位将流入计算H+B.在这方面,所有寄存器对都是相似的.

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

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

  • 我不完全理解这个问题,但是:如果你将 HL 写入内存,那么 Z80 将写入 L,然后 H。如果模拟器将 HL 放在屏幕上供人类使用,它将打印 H 然后 L,因为它知道你正在输出16 位数量,这就是它们的写法。相反,如果您将“5A”和“E5”存储到内存中,然后将内存输出给人类,它将逐字节打印,因为这就是内存的写入方式。如果从该地址读取 HL,它将先是 L,然后是 H,给出 16 位值“E55A”。 (2认同)