有人能解释一下xchg指令在下一个代码中是如何工作的吗?假定 arrayD 是一个1,2,3的DWORD数组。
xchg
mov eax, arrayD ; eax=1 xchg eax, [arrayD+4] ; eax=2 arrayD=2,1,3
为什么xchg后面的数组不是1,1,3?
apeeds0o1#
xchg工作原理like Intel's documentation says。我认为第二行的注解是错误的。**它应该是eax=2,arrayD = 1,1,3。**所以你是正确的,你应该给你的讲师发电子邮件,告诉他你发现了一个错误,除非你在笔记中遗漏了什么。xchg只存储一个元素,它无法及时地回溯以了解eax中的值来自何处,并使用一条xchg指令交换两个内存位置。在一条指令中将1,2交换为2,1的唯一方法是64位循环,如rol qword ptr [arrayD], 32(仅限x86-64)。
eax=2
arrayD = 1,1,3
1,2
2,1
rol qword ptr [arrayD], 32
顺便说一句,如果你关心性能,不要使用xchg和内存操作数。它在386和更高版本上有一个隐式的lock前缀,所以它是一个完整的内存屏障,甚至除了等待存储缓冲区耗尽之外,在Haswell/Skylake上它需要大约20个CPU周期(http://agner.org/optimize/和https://uops.info/).当然,多个指令可以同时运行,但是xchg mem,reg是8个微操作,而单独的加载+存储总共是2个微操作。xchg不会使流水线停滞,但是内存障碍会造成很大的伤害(阻止后面的加载提前开始,以及等待前面的加载和存储完全完成)。
lock
xchg mem,reg
相关:
xchg reg,reg
mfence
1条答案
按热度按时间apeeds0o1#
xchg
工作原理like Intel's documentation says。我认为第二行的注解是错误的。**它应该是
eax=2
,arrayD = 1,1,3
。**所以你是正确的,你应该给你的讲师发电子邮件,告诉他你发现了一个错误,除非你在笔记中遗漏了什么。xchg
只存储一个元素,它无法及时地回溯以了解eax中的值来自何处,并使用一条xchg
指令交换两个内存位置。在一条指令中将
1,2
交换为2,1
的唯一方法是64位循环,如rol qword ptr [arrayD], 32
(仅限x86-64)。顺便说一句,如果你关心性能,不要使用
xchg
和内存操作数。它在386和更高版本上有一个隐式的lock
前缀,所以它是一个完整的内存屏障,甚至除了等待存储缓冲区耗尽之外,在Haswell/Skylake上它需要大约20个CPU周期(http://agner.org/optimize/和https://uops.info/).当然,多个指令可以同时运行,但是xchg mem,reg
是8个微操作,而单独的加载+存储总共是2个微操作。xchg
不会使流水线停滞,但是内存障碍会造成很大的伤害(阻止后面的加载提前开始,以及等待前面的加载和存储完全完成)。相关:
xchg
只在这种情况下有用,如果你需要原子性,或者你关心代码大小而不是速度。或者在386之前的CPU上,xchg
并不意味着lock
。xchg reg,reg
,无内存屏障)mfence
与lock
ed操作之间得指令级并行性