我想模拟x86/x86_64上禁止未对齐内存访问的系统。是否有一些调试工具或特殊模式来执行此操作?
当使用为SPARC或其他类似CPU设计的软件(C/C)时,我想在几台x86/x86_64PC上运行许多(CPU密集型)测试。但是我对Sparc的访问是有限的。
正如我所知,Sparc总是检查内存读写的对齐是否正常(从任何地址读取一个字节,但仅当地址可被4整除时才允许读取一个4字节的字)。
可能是Valgrind或PIN有这样的模式?或者编译器的特殊模式?我正在搜索Linux非商业工具,但也允许使用windows工具。
或者EFLAGS中是否有秘密CPU标志?
GCC和Clang都内置了UndefinedBehaviorSanitizer。其中一项检查“对齐”(alignment)可以通过使用-fsanize=alignment启用。它将发出代码,在运行时检查指针对齐,如果未对齐的指针被取消引用,则终止。
请参阅在线文档:
这很棘手,我没有亲自做过,但我认为你可以通过以下方式来做:
x86\u 64 CPU(特别是我已经检查过Intel Corei7,但我想其他CPU也一样)有一个性能计数器disalign\u MEM\u REF,用于计数器未对齐的内存引用。
因此,首先,您可以在Linux下运行程序并使用“perf”工具来统计代码执行的未对齐访问的数量。
一种更为棘手和有趣的方法是编写一个内核模块,对性能计数器进行编程,以在溢出时生成中断,并使其溢出第一个未对齐的加载/存储。在内核模块中响应此中断,但向html" target="_blank">进程发送信号。
实际上,这将把x86\u 64变成一个不支持未对齐访问的核心。
但这并不简单——除了代码之外,系统库还使用未对齐的访问,因此很难将它们与您自己的代码分开。
我刚刚阅读了一个问题,未对齐的内存访问是否总是会导致总线错误?链接到维基百科文章Segtion Fault。
在这篇文章中,有一个很好的提示,提醒我们不要忘记非常罕见的英特尔处理器标志AC,也就是对齐检查。
下面是如何启用它(来自维基百科的总线错误示例,修复了x86-64 System V的红色区域重击错误,因此这在Linux和MacOS上是安全的,并从Basic ash转换而来,这在函数内部从来都不是一个好主意:您希望对AC的更改是有序的。内存访问。
#if defined(__GNUC__)
# if defined(__i386__)
/* Enable Alignment Checking on x86 */
__asm__("pushf\n orl $0x40000,(%%esp)\n popf" ::: "memory");
# elif defined(__x86_64__)
/* Enable Alignment Checking on x86_64 */
__asm__("add $-128, %%rsp \n" // skip past the red-zone, in case there is one and the compiler has local vars there.
"pushf\n"
"orl $0x40000,(%%rsp)\n"
"popf \n"
"sub $-128, %%rsp" // and restore the stack pointer.
::: "memory"); // ordered wrt. other mem access
# endif
#endif
一旦启用,它的工作原理就像/proc/cpu/对准
中的ARM对齐设置一样,请参阅答案如何捕获未对齐的内存访问?例如。
此外,如果您使用的是GCC,我建议您启用警告。为具有严格对齐要求的目标构建时(例如ARM),GCC将报告可能导致未对齐内存访问的位置。
但是请注意,libc手写的memcpy和其他函数仍然会进行未对齐的访问,因此在x86(包括x86-64)上设置AC通常是不实用的。即使您的源没有,GCC有时也会发出使未对齐访问成为未对齐访问的ash,例如作为一次复制或归零两个相邻数组元素或结构成员的优化。
问题内容: 我想用x86 / x86_64上禁止的未对齐内存访问来模拟系统。有一些调试工具或特殊模式可以做到这一点吗? 当使用为SPARC或其他类似CPU设计的软件(C / C ++)时,我想在几台x86 / x86_64 PC上运行许多(CPU密集型)测试。但是我对Sparc的访问受到限制。 据我所知,Sparc总是检查内存读写的对齐是否自然(从任何地址读取一个字节,但仅当地址被4整除时才读取4
一般有两种类型的SIMD指令: A、 使用对齐内存地址的,如果地址在操作数大小边界上未对齐,则会引发一般保护(#GP)异常: B.以及那些与未对齐的内存地址一起工作的,不会引发此类异常: 但我只是好奇,为什么我要开枪打自己的脚,并使用第一组的对齐内存指令呢?
我总是听说未对齐的访问是不好的,因为它们要么会导致运行时错误并使程序崩溃,要么会减慢内存访问速度。但是我找不到任何关于它们会减慢多少速度的实际数据。 假设我在x86上并且有一些(但未知的)未对齐访问份额——实际上可能的最糟糕的减速是什么,以及如何在不消除所有未对齐访问并比较两个版本代码的运行时间的情况下估计它?
也许我误解了什么,但x86中的未对齐访问似乎带来了安全问题,例如返回地址完整性问题。 > 为什么x86设计器首先允许未对齐的访问?(性能是我能想到的唯一好处。) 如果x86设计人员允许这种未对齐的访问问题,他们应该知道如何解决它,不是吗?是否可以使用静态技术或清理技术检测未对齐的访问?
问题内容: 我出于好奇而学习x86汇编。我目前正在使用带有NASM汇编器的基于Linux的操作系统。我很难理解为什么 会导致分段错误(将ebx寄存器的内容移至内存位置0xFFF时)。我当时以为在纯asm中构建程序将使我能够不受限制地访问进程的虚拟地址空间。不是吗? 您将如何在程序集中实现类似堆的内容? 问题答案: 在Linux(x86)上-尽管您的进程中的虚拟地址范围为4gb,但并非所有虚拟地址都
在回答中,我说过长期以来(在x86/x86_64上)未对齐的访问速度几乎与对齐的访问速度相同。我没有任何数字来支持这个说法,所以我为它创建了一个基准。 你看到这个基准有什么缺陷吗?你能改进它吗(我的意思是,增加GB/秒,以便更好地反映真相)?