【发布时间】:2019-08-11 11:05:03
【问题描述】:
我在 Windows 上使用 64 位 NASM 为 malloc 分配了一块内存。当我使用 movapd (移动两个对齐的打包双精度浮点值)时,我的程序崩溃,但我可以使用 movupd (移动两个未对齐的打包双精度浮点点值)。
我更改为_aligned_malloc 指定alignment=16,它可以分配内存,但是当我使用movapd 时仍然出现错误。在执行指令之前,我的调试器显示 R8=0xB0FC78、R15=0x12FC0050、RCX=0x6D40050 和 RDX = 0x10010050。 RCX 和 RDX 是指向两个内存块的指针。 R8 和 RCX 是跨块的计数器
这行得通:
movupd xmm0,[rdx+r8]
movupd [r15+rcx],xmm0
这会崩溃:
movapd xmm0,[rdx+r8]
movapd [r15+rcx],xmm0
奇怪的是,使用 _aligned_malloc 的程序比使用 malloc 的内存要慢。
我的代码是用 NASM(汇编语言)编写的,但我认为语言并不重要。
为什么即使使用_aligned_malloc 分配的内存,我也不能使用 movapd?
【问题讨论】:
-
就在这些指令执行之前,调试器所说的 rdx、r8、r15 和 rcx 中的值是多少?我只能猜测,当计算 rdx+r8 和/或 r15+rcx 时,结果地址没有正确对齐。
-
我现在正在获取该信息。我会在几分钟后回来。
-
最终有效地址不能对齐。除了对齐之外,没有任何设置会使
movapd崩溃,但movupd会成功。使用您的调试器。您是否忘记按sizeof(double) = 8或其他方式缩放数组偏移量? -
在 HEX 中更易于阅读。 r8=B0FC78, r15=12FC0050 rcx=6D40050 rdx=10010050
-
r8 的最后一个半字节(最后 4 位)没有 0,因此当添加到已对齐的 rdx 时,它会破坏对齐。(rdx 的低半字节为 0)
标签: windows assembly x86-64 simd memory-alignment