Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 将位字段转换为uint8\t_C_Struct_Casting_Bit Fields_Uint8t - Fatal编程技术网

C 将位字段转换为uint8\t

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,以便将其推送到堆栈中。但是,下面

下面的我的位字段表示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
,以便将其推送到堆栈中。但是,下面的代码给出了此错误:
需要算术或指针类型的“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