首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >访问跨越MMU页面边界的变量

访问跨越MMU页面边界的变量
EN

Stack Overflow用户
提问于 2022-06-02 16:31:31
回答 1查看 138关注 0票数 3

我正在学习X64汇编语言在Windows和MASM64的最新版本的书“64位汇编语言的艺术”。

关于这本书的引语,我有一个问题:

--在一种情况下,您需要担心内存中的MMU页面组织。有时,在内存中数据结构结束后访问(读取)数据是很方便的。但是,如果该数据结构与MMU页的结尾对齐,那么访问内存中的下一个页面可能会有问题。内存中的某些页面是不可访问的;MMU不允许在该页面上进行读取、写入或执行。尝试这样做将产生x86-64通用保护(分段)错误,并中止程序的正常执行。如果您有跨越页边界的数据访问权限,而内存中的下一页无法访问,则会使您的程序崩溃。例如,考虑在MMU页面的末尾访问一个字节对象,如图3-2所示。

通常情况下,您不应该在数据结构结束后读取数据。如果出于某种原因您需要这样做,您应该确保访问内存中的下一页是合法的(唉,没有关于现代x86-64 CPU的指令来允许这样做;确保访问是合法的唯一方法是确保在您正在访问的数据结构之后有有效的数据)。

所以我的问题是:假设我有确切的案例。数据段末尾的单词变量。我如何防止这种例外情况?手工填充00h细胞?正确地调整每个变量的大小?如果我对齐了所有,如果最后一个变量是一个跨越4k边界的qword,会发生什么呢?如何防止这种情况发生?

MASM会自动分配另一个顺序数据段来容纳它吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-06-02 18:18:52

在已知包含任何有效字节的页面中的任何位置读取都是安全的,例如在静态存储中使用未对齐的foo: dq 1。如果有,mov rax, [foo]总是安全的。

您的汇编程序+链接器将确保.data.rdata.bss中的所有存储实际上都得到操作系统允许您触摸的有效页面的支持。

您的书的重点是,您可能有一个数组的3字节结构,如RGB像素,例如。x86没有3字节的加载,所以用mov eax, [rcx]加载整个像素结构实际上会加载4个字节,包括你不关心的1个字节。

通常情况下,这很好,除非[rcx+3]位于未映射的页面中。(例如,缓冲区的最后一个像素,结束于页的末尾,下一页未映射)。进入另一条您不需要数据的缓存行对于性能来说不是很好,因此这是与2或3个单独的负载(如movzx eax, word ptr [rcx] / movzx edx, byte ptr [rcx+2] )的权衡

这在SIMD中比较常见,在加载这些元素之后,您可以在寄存器中一次更多地使用多个元素。像movdqu xmm0, [rcx]一样,加载16个字节,包括5个完整像素和另一个像素的1个字节,我们不会在这个向量中处理。

(在平面RGB中,所有R分量都是连续的,您没有这个问题。或者一般情况下,AoS与SoA =数组的结构对SIMD很好。如果用3展开循环,那么3x16字节向量=48个字节,覆盖16x3字节像素,如果需要的话,也可以做一些调整,或者如果需要不同的常量来排列不同的结构或像素或其他组件,也没有这个问题。)

如果循环遍历一个数组,那么在最后的迭代中也会遇到同样的问题。如果数组大于1 SIMD向量(XMM或YMM),而不是最后一个n % 4元素的标量,则有时可以安排执行一个在数组末尾结束的SIMD加载,因此它与以前的完全向量部分重叠。(为了减少分支,留下1..4个清理元素,而不是0..3,所以如果n是向量宽度的倍数,那么“清除”就是另一个完整的向量。)这对于创建一个ASCII字符串的小写副本非常有用:在任何给定的字节上重做工作都很好,而且您没有存储在原地,所以您甚至没有存储转发停止,因为您不会有一个负载重叠在以前的商店。对数组进行求和(需要避免重复计数)或就地工作就不那么容易了。

另见Is it safe to read past the end of a buffer within the same page on x86 and x64?

这对strlen来说是一个挑战,因为您不知道允许读取的数据是否扩展到下一页。(除非一次只读取一个字节,这比使用SSE2时慢了16倍。)

AVX-512具有屏蔽负载/存储的故障抑制功能,因此带有vmovdqu8 xmm0{k1}{z}, [rcx]的k1=0x7F实际上是15字节的负载,即使16字节(掩码为0)扩展到未映射的页面,也不会出现故障。同样适用于AVX、vmaskmovps等。但在AMD上,这款手机的商店版本却很慢。

另见Vectorizing with unaligned buffers: using VMASKMOVPS: generating a mask from a misalignment count? Or not using that insn at all

尝试这样做的

将生成x86-64通用保护(分段)错误。

实际上,对于触及未映射或权限拒绝页面的访问,#PF页面错误。但是的,同样的不同。

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

https://stackoverflow.com/questions/72479456

复制
相关文章

相似问题

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