JL2*_*210 -1 c z80 emulation type-punning
Follow-up to extended discussion in Casting behavior in C
I'm trying to emulate a Z80 in C, where several 8-bit registers can be combined to create 16-bit registers.
This is the logic I'm trying to use:
struct {
uint8_t b;
uint8_t c;
uint16_t *bc;
} regs[1];
...
regs->bc = (uint16_t *)&(regs->b);
Run Code Online (Sandbox Code Playgroud)
Why is this incorrect, and how can I do it correctly (using type-punning if needed)?
I need to do this multiple times, preferably within the same structure.
For those of you that I haven't mentioned this to: I understand that this assumes a little-endian architecture. I have this handled completely.
这是不正确的,因为b它的类型uint8_t和指向的指针uint16_t不能用于访问此类变量。它可能未正确对齐,并且是严格的别名冲突。
但是,您可以自由执行(uint8_t *)®s或(struct reg_t*)®s->b,因为(6.7.2.1/15)
指向适当转换的结构对象的指针指向其初始成员,反之亦然。
在进行与硬件相关的编程时,请确保不要使用带符号的类型。这意味着更改intn_t为uintn_t。
至于如何正确键入pun,请使用并集:
typedef union
{
struct /* standard C anonymous struct */
{
uint8_t b;
uint8_t c;
};
uint16_t bc;
} reg_t;
Run Code Online (Sandbox Code Playgroud)
然后可以将其分配为指向16位硬件寄存器,如下所示:
volatile reg_t* reg = (volatile reg_t*)0x1234;
Run Code Online (Sandbox Code Playgroud)
0x1234硬件寄存器地址在哪里。
注意:此联合是与病情相关的。b将访问bc大字节序系统上的MS字节,但bc访问小字节序系统上的LS字节。