C 将位字段转换为uint8\t
下面的我的位字段表示6502 CPU的7个状态标志。我试图模拟指令C 将位字段转换为uint8\t,c,struct,casting,bit-fields,uint8t,C,Struct,Casting,Bit Fields,Uint8t,下面的我的位字段表示6502 CPU的7个状态标志。我试图模拟指令php,它将状态标志的副本推送到堆栈上 struct Flags { uint8_t C: 1; uint8_t Z: 1; uint8_t I: 1; uint8_t D: 1; uint8_t V: 1; uint8_t N: 1; uint8_t B: 2; }; 我需要一种方法将每个字段打包成一个单字节数据类型,如uint8\u t,以便将其推送到堆栈中。但是,下面
php
,它将状态标志的副本推送到堆栈上
struct Flags {
uint8_t C: 1;
uint8_t Z: 1;
uint8_t I: 1;
uint8_t D: 1;
uint8_t V: 1;
uint8_t N: 1;
uint8_t B: 2;
};
我需要一种方法将每个字段打包成一个单字节数据类型,如uint8\u t
,以便将其推送到堆栈中。但是,下面的代码给出了此错误:需要算术或指针类型的“struct Flags”类型的操作数
。如何解决这个问题
int main() {
struct Flags f = {0, 0, 0, 0, 1, 0, 0};
uint8_t f_as_byte = (uint8_t) f;
}
您可以使用
接头执行此操作
:
typedef unsigned char uint8_t;
struct Flags {
uint8_t C:1;
uint8_t Z:1;
uint8_t I:1;
uint8_t D:1;
uint8_t V:1;
uint8_t N:1;
uint8_t B:2;
};
union uFlags {
uint8_t B;
struct Flags F;
};
int
main()
{
struct Flags f = { 0, 0, 0, 0, 1, 0, 0 };
union uFlags u;
u.F = f;
uint8_t f_as_byte = u.B;
}
使用指定的初始值设定项,您可以直接初始化
联合
,而无需单独的f
:
typedef unsigned char uint8_t;
struct Flags {
uint8_t C:1;
uint8_t Z:1;
uint8_t I:1;
uint8_t D:1;
uint8_t V:1;
uint8_t N:1;
uint8_t B:2;
};
union uFlags {
uint8_t B;
struct Flags F;
};
int
main()
{
union uFlags u = {
.F = { .V = 1 }
};
uint8_t f_as_byte = u.B;
}
您可以使用
接头执行此操作
:
typedef unsigned char uint8_t;
struct Flags {
uint8_t C:1;
uint8_t Z:1;
uint8_t I:1;
uint8_t D:1;
uint8_t V:1;
uint8_t N:1;
uint8_t B:2;
};
union uFlags {
uint8_t B;
struct Flags F;
};
int
main()
{
struct Flags f = { 0, 0, 0, 0, 1, 0, 0 };
union uFlags u;
u.F = f;
uint8_t f_as_byte = u.B;
}
使用指定的初始值设定项,您可以直接初始化
联合
,而无需单独的f
:
typedef unsigned char uint8_t;
struct Flags {
uint8_t C:1;
uint8_t Z:1;
uint8_t I:1;
uint8_t D:1;
uint8_t V:1;
uint8_t N:1;
uint8_t B:2;
};
union uFlags {
uint8_t B;
struct Flags F;
};
int
main()
{
union uFlags u = {
.F = { .V = 1 }
};
uint8_t f_as_byte = u.B;
}
位字段的问题在于它是按位的排列顺序定义的。对于6502仿真器来说,这可能是不可接受的。
PHP
命令必须以所需的格式推送状态字,例如
uint8_t as_state = f.N << 7 | f.V << 6 | f.B << 4 | f.D << 3 | f.I << 2 | f.Z << 1 | f.C;
#define FLAG_N 0x80U
...
#define FLAG_C 0x1U
#define SET_FLAG(flag_var, flag) ((flag_var) |= (flag))
#define CLR_FLAG(flag_var, flag) ((flag_var) &= ~(flag))
#define GET_FLAG(flag_var, flag) ((_Bool)((flag_var) & (flag)))
uint8_t flags = 0;
SET_FLAG(flags, FLAG_C);
if (GET_FLAG(flags, FLAG_N)) { ... }
这样就可以对PHP
指令进行编码,只需按原样推送标志
位字段的问题在于它是按照位的排列顺序定义的。对于6502仿真器来说,这可能是不可接受的。
PHP
命令必须以所需的格式推送状态字,例如
uint8_t as_state = f.N << 7 | f.V << 6 | f.B << 4 | f.D << 3 | f.I << 2 | f.Z << 1 | f.C;
#define FLAG_N 0x80U
...
#define FLAG_C 0x1U
#define SET_FLAG(flag_var, flag) ((flag_var) |= (flag))
#define CLR_FLAG(flag_var, flag) ((flag_var) &= ~(flag))
#define GET_FLAG(flag_var, flag) ((_Bool)((flag_var) & (flag)))
uint8_t flags = 0;
SET_FLAG(flags, FLAG_C);
if (GET_FLAG(flags, FLAG_N)) { ... }
这样就可以对PHP
指令进行编码,只需按原样推送标志
不应将结构转换为
(uint8\u t)
,而应将其地址转换为(uint8\u t*)
:
#包括
结构标志{
uint8_t C:1;
uint8_t Z:1;
uint8_t I:1;
uint8_t D:1;
uint8_tV:1;
uint8 N:1;
uint8_t B:2;
};
int main(){
结构标志f={0,0,0,0,1,0,0};
uint8_t f_as_byte=*(uint8_t*)&f;
printf(“标志:%.2X\n”,f作为字节);
返回0;
}
但是请注意,用于表示位字段成员的实际位值是由实现定义的。C标准甚至不能保证
标志
结构适合单个字节。这使得位字段成为表示硬件寄存器或指令操作码的危险选择,因为这样会使仿真器不可移植。Little-endian和big-endian系统通常对位字段成员使用不同的布局。不应将结构转换为(uint8\u t)
,而应将其地址转换为(uint8\u t*)
:
#包括
结构标志{
uint8_t C:1;
uint8_t Z:1;
uint8_t I:1;
uint8_t D:1;
uint8_tV:1;
uint8 N:1;
uint8_t B:2;
};
int main(){
结构标志f={0,0,0,0,1,0,0};
uint8_t f_as_byte=*(uint8_t*)&f;
printf(“标志:%.2X\n”,f作为字节);
返回0;
}
但是请注意,用于表示位字段成员的实际位值是由实现定义的。C标准甚至不能保证
标志
结构适合单个字节。这使得位字段成为表示硬件寄存器或指令操作码的危险选择,因为这样会使仿真器不可移植。Little-endian和big-endian系统通常对位字段成员使用不同的布局。@chux修复:D@chux-修订日期:D