首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >4字节错对齐写入地址

4字节错对齐写入地址
EN

Stack Overflow用户
提问于 2013-04-10 23:52:13
回答 1查看 390关注 0票数 1

我正在做一个CHibiOS实时操作系统到lm32微处理器的端口。

我在第一行代码中出现了内存地址对齐错误的问题,我将其编码为设置一个新线程。其他三行在试图写入内存时已经给了我一个类似的问题,但我解决了它对intctxcontext结构放置__attribute__((packed));的问题。

守则如下:

代码语言:javascript
复制
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;

在我实现的头文件中定义了这些结构:

代码语言:javascript
复制
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进行调试,当它尝试执行行时:

代码语言:javascript
复制
tp->p_ctx.sp = (struct intctx*)((uint32_t *)wsp + size - sizeof(struct intctx)); 

它提出了以下问题:

代码语言:javascript
复制
core: 4 byte misaligned write to address 0x107409 at 0x100b20

Program received signal SIGBUS, Bus error.
0x00000080 in ?? ()

有谁可以帮我?谢谢。

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

在ChibiOS支持的其他体系结构中,代码行是在相同的函数中实现的,我只这样做了:

代码语言:javascript
复制
tp->p_ctx.sp =  (struct intctx*)((uint32_t *)wsp + size - sizeof(struct intctx));

这是一个完整的功能:

代码语言:javascript
复制
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);
}
EN

回答 1

Stack Overflow用户

发布于 2013-04-11 05:50:22

wsp的类型是什么?我建议一组字符,或者您定义为不需要适当对齐来存储int32_t类型的其他任何东西。考虑总线是如何按照常规方式对齐的,以检索32位组中的int32_t值。现在考虑一下在体系结构级别上“总线错误”实际上意味着什么:

  1. 检索该值需要多个fetch (性能方面不理想),或
  2. 您的程序故障(更糟)

在常见的Intel实现中,它使用第一个选项,除非您或您的调试器向您的程序注入了一些程序的疯狂(例如,请参阅这篇维基百科文章)。在C中,它只是简单的未定义的行为。确保wsp适当地对齐以指向int32_t类型。您可以通过确保它指向以下其中之一来做到这一点:

  1. int32_t变量,或
  2. 数组中的任何int32_t对象,或:
  3. malloc、calloc或realloc的返回值,或:
  4. 任何int32_t对象“malloc/calloc/realloc返回值被视为指向int32_t的指针”。

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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15938525

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档