在x86失去定位球 [英] Mis-aligned pointers on x86

查看:189
本文介绍了在x86失去定位球的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有人可以提供一个例子是铸造从一种类型到另一个指针失败,因为失准?

Can someone provide an example were casting a pointer from one type to another fails due to mis-alignment?

在评论<一个href="http://stackoverflow.com/questions/544928/reading-integer-size-bytes-from-a-char-array/544964#544964">this回答,bothie指出,做这样的事情

In the comments to this answer, bothie states that doing something like

char * foo = ...;
int bar = *(int *)foo;

可能导致即使在x86错误,如果比对检查启用。

might lead to errors even on x86 if alignment-checking is enabled.

我试图通过设置$ PS设置对齐检查标志之后产生一个错误条件| =(1&LT;&LT; 18)在GDB ,但什么都没有发生。

I tried to produce an error condition after setting the alignment-check flag via set $ps |= (1<<18) in GDB, but nothing happened.

什么是一个工作(即非工作;))的例子看起来像

What does a working (ie non-working ;)) example look like?


从没有答案的code段的失败对我的系统 - 我会尝试用不同的编译器版本,并在不同的PC以后

None of the code snippets from the answers fail on my system - I'll try it with a different compiler version and on a different pc later.

顺便说一句,我自己的测试code这个样子(现在也在使用ASM设置 C 标记和未对齐的读,写):

Btw, my own test code looked like this (now also using asm to set AC flag and unaligned read and write):

#include <assert.h>

int main(void)
{
    #ifndef NOASM
    __asm__(
        "pushf\n"
        "orl $(1<<18),(%esp)\n"
        "popf\n"
    );
    #endif

    volatile unsigned char foo[] = { 1, 2, 3, 4, 5, 6 };
    volatile unsigned int bar = 0;

    bar = *(int *)(foo + 1);
    assert(bar == 0x05040302);

    bar = *(int *)(foo + 2);
    assert(bar == 0x06050403);

    *(int *)(foo + 1) = 0xf1f2f3f4;
    assert(foo[1] == 0xf4 && foo[2] == 0xf3 && foo[3] == 0xf2 &&
        foo[4] == 0xf1);

    return 0;
}

断言通过没有问题,即使产生code肯定包含对齐访问 MOV -0x17(%EBP),%EDX MOVL $ 0xf1f2f3f4,-0x17(%EBP)


所以才会设置 C 触发 SIGBUS 或没有?我无法得到它在Windows XP下我的英特尔双核笔记本电脑工作,没有一个版本的GCC的我测试(MinGW的-3.4.5,MinGW的-4.3.0,Cygwin的-3.4.4),而codelogic和乔纳森·莱弗勒提到的基于x86的失败......

So will setting AC trigger a SIGBUS or not? I couldn't get it to work on my Intel dual core laptop under Windows XP with none of the GCC versions I tested (MinGW-3.4.5, MinGW-4.3.0, Cygwin-3.4.4), whereas codelogic and Jonathan Leffler mentioned failures on x86...

推荐答案

还有一个附加条件,没有提及,对于EFLAGS.AC真正生效。 CR0.AM必须从绊倒在旧操作系统predating的486有没有处理这个异常设置为prevent INT 17H。不过,Windows默认不设置它,你需要编写一个内核模式驱动程序进行设置。

There is an additional condition, not mentioned, for EFLAGS.AC to actually take effect. CR0.AM must be set to prevent INT 17h from tripping on older OSes predating the 486 that have no handler for this exception. Unfortunately, Windows do not set it by default, you need to write a kernel-mode driver to set it.

这篇关于在x86失去定位球的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆