C 4字节未对齐写入地址

C 4字节未对齐写入地址,c,memory,C,Memory,我正在做一个连接到lm32微处理器的CHibiOS RTOS端口 我有一个错误的内存地址在第一行代码,我编码设置一个新的线程。 其他三行在试图写入内存时已经给了我类似的问题,但我通过对齐intctx和contextstruct-put\uu-attribute_uuu((打包)),解决了这个问题 代码如下: tp->p_ctx.sp = (struct intctx*)((uint32_t *)wsp + size - sizeof(struct intctx)); tp->p_ct

我正在做一个连接到lm32微处理器的CHibiOS RTOS端口

我有一个错误的内存地址在第一行代码,我编码设置一个新的线程。 其他三行在试图写入内存时已经给了我类似的问题,但我通过对齐
intctx
context
struct-put
\uu-attribute_uuu((打包)),解决了这个问题

代码如下:

tp->p_ctx.sp = (struct intctx*)((uint32_t *)wsp + size - sizeof(struct intctx));
tp->p_ctx.sp->r1 = (uint32_t)arg;
tp->p_ctx.sp->r2 = (uint32_t)pf;
tp->p_ctx.sp->ra = (uint32_t)port_thread_start;
结构在我实现的头文件中定义:

struct intctx {
uint32_t r1;
uint32_t r2;
uint32_t r3;
uint32_t r4;
uint32_t r5;
uint32_t r6;
uint32_t r7;
uint32_t r8;
uint32_t r9;
uint32_t r10;
uint32_t r11;
uint32_t r12;
uint32_t r13;
uint32_t r14;
uint32_t r15;
uint32_t r16;
uint32_t r17;
uint32_t r18;
uint32_t r19;
uint32_t r20;
uint32_t r21;
uint32_t r22;
uint32_t r23;
uint32_t r24;
uint32_t r25;
uint32_t gp;
uint32_t fp;
uint32_t sp;
uint32_t ra;
uint32_t ea;
uint32_t ba;
} __attribute__((packed));

struct context {
struct intctx *sp;
} __attribute__((packed));
我使用gdb进行调试,当它尝试执行该行时:

tp->p_ctx.sp = (struct intctx*)((uint32_t *)wsp + size - sizeof(struct intctx)); 
它给出了以下问题:

core: 4 byte misaligned write to address 0x107409 at 0x100b20

Program received signal SIGBUS, Bus error.
0x00000080 in ?? ()
有人能帮我吗?多谢各位



wsp作为这些代码行所在函数的参数通过引用传递。 wsp的类型为void*: 但这是一个Thread*类型,wsp指向空闲线程结构

这行代码在ChibiOS支持的其他体系结构中以相同的功能实现,我只做了相同的操作:

tp->p_ctx.sp =  (struct intctx*)((uint32_t *)wsp + size - sizeof(struct intctx));
这是完整的功能:

Thread *chThdCreateI(void *wsp, size_t size,
                 tprio_t prio, tfunc_t pf, void *arg) {
/* Thread structure is laid out in the lower part of the thread workspace.*/
Thread *tp = wsp;

chDbgCheckClassI();

chDbgCheck((wsp != NULL) && (size >= THD_WA_SIZE(0)) &&
         (prio <= HIGHPRIO) && (pf != NULL),
         "chThdCreateI");
tp->p_ctx.sp =  (struct intctx*)((uint32_t *)wsp + size - sizeof(struct intctx));
tp->p_ctx.sp->r1 = (uint32_t)arg;
tp->p_ctx.sp->r2 = (uint32_t)pf;
tp->p_ctx.sp->ra = (uint32_t)port_thread_start;
//SETUP_CONTEXT(wsp, size, pf, arg);
return _thread_init(tp, prio);
}
Thread*chThdCreateI(void*wsp,size\u t size,
tprio_t prio,tfunc_t pf,void*arg){
/*线程结构布置在线程工作区的下部*/
线程*tp=wsp;
chDbgCheckClassI();
chDbgCheck((wsp!=NULL)和&(大小>=THD_WA_大小(0))&&
(prio p_ctx.sp=(struct intctx*)((uint32_t*)wsp+size-sizeof(struct intctx));
tp->p_ctx.sp->r1=(uint32_t)参数;
tp->p_ctx.sp->r2=(uint32_t)pf;
tp->p_ctx.sp->ra=(uint32_t)端口线程开始;
//设置上下文(wsp、大小、pf、参数);
返回线程初始化(tp,prio);
}

< /代码> 什么类型的WSP?我建议一个字符数组,或者任何你定义的字符数组都不需要被适当地对齐来存储<代码> It32×t < /代码>类型。考虑总线是如何常规对齐来检索<代码> IT32的T < /COD>以32位为单位排列的值。现在考虑什么是“总线错误”。实际上可能意味着在架构级别:

  • 检索该值需要多次提取(性能方面不理想),或
  • 您的程序出现故障(甚至更糟)
  • 在常见的英特尔实现中,它使用第一个选项,除非您或您的调试器向您的程序注入一些汇编疯狂(例如,请参阅)。在C中,这只是简单的未定义行为。请确保wsp与指向
    int32\t
    类型的点适当对齐。您可以通过确保它指向以下其中一种类型来完成此操作:

  • int32\t
    变量,或
  • 数组中的任何
    int32\t
    对象,或:
  • malloc、calloc或realloc的返回值,或:
  • “malloc/calloc/realloc返回值被视为指向
    int32\u t
    的指针”的任何
    int32\u t
    对象

  • 我认为你对指针算法感到困惑。你在读哪本书?

    什么是WSP的类型?我建议一个字符数组,或者你定义的任何数组都不需要被适当地对齐来存储<代码>值在32位组中对齐。现在考虑“总线错误”在架构级别上可能意味着什么:

  • 检索该值需要多次提取(性能方面不理想),或
  • 您的程序出现故障(甚至更糟)
  • 在常见的英特尔实现中,它使用第一个选项,除非您或您的调试器向您的程序注入一些汇编疯狂(例如,请参阅)。在C中,这只是简单的未定义行为。请确保wsp与指向
    int32\t
    类型的点适当对齐。您可以通过确保它指向以下其中一种类型来完成此操作:

  • int32\t
    变量,或
  • 数组中的任何
    int32\t
    对象,或:
  • malloc、calloc或realloc的返回值,或:
  • “malloc/calloc/realloc返回值被视为指向
    int32\u t
    的指针”的任何
    int32\u t
    对象

  • 我想你对指针算法感到困惑。你在读哪本书?

    打包如何解决未对齐问题。在调试器中,在执行讨论中的行之前,你是否尝试过检查
    wsp
    size
    的值?打包如何解决未对齐问题。在调试器中,你尝试过吗d要在执行讨论中的行之前检查
    wsp
    size
    的值,wsp作为这些代码行所在函数的参数通过引用传递。wsp作为这些代码行所在函数的参数通过引用传递。