返回信息流☆─────────────────────────────────────☆
flyingkisser (齐天大猫) 于 (Wed Nov 12 09:43:06 2008) 提到:
从debugman上转来的,大家有空可以思考思考。
关于 lock cmpxchg8b...
#include <windows.h>
#include <iostream>
#include <iomanip>
using namespace std;
volatile unsigned long long a = 0;
DWORD __stdcall ThreadProc(LPVOID Dummy)
{
__asm {
lea esi, a;
xor eax, eax;
xor edx, edx;
mov ecx, 0xffffffff;
mov ebx, 0xffffffff;
loc_xxx:
lock cmpxchg8b [esi];
xor eax, ebx;
xor ebx, eax;
xor eax, ebx;
xor ecx, edx;
xor edx, ecx;
xor ecx, edx;
jmp loc_xxx;
}
return 0;
}
int main()
{
DWORD ThreadId;
HANDLE hThread;
long long t;
hThread = CreateThread(0, 0, ThreadProc, 0, 0, &ThreadId);
CloseHandle(hThread);
while (true)
{
t = a;
if (t != 0 && t != 0xffffffffffffffff) cout << hex << setw(16) << t << endl;
}
return 0;
}
如果 lock cmpxchg8b 是原子性操作, 那么这段程序应该没有输出才是, 但是在双核机上是有输出的.
但是, 将进程亲和设置为一个 cpu 以后, 仍然有少量的输出. 这是哪里的问题呢?
☆─────────────────────────────────────☆
flyingmiao (amiao) 于 (Wed Nov 12 11:30:39 2008) 提到:
呃。。。。不懂。。。
猫哥解释一下。。。
lock cmpxchg8b [esi]; 会造成死锁?
☆─────────────────────────────────────☆
CNLAS (愛すべきもの) 于 (Wed Nov 12 12:07:17 2008) 提到:
比较交换...[esi]的值也就是a的值不停的0和0xffffffffffffffff之间交换...
而且用lock前缀保持原子...
变量a也是volatile的
所以问题必然出在汇编代码之外...
这个问题很有意思哇...前两天部门里还在说32位和64位的区别呢...嗯...爬走吃饭...
【 在 flyingmiao 的大作中提到: 】
: 呃。。。。不懂。。。
: 猫哥解释一下。。。
: lock cmpxchg8b [esi]; 会造成死锁?
☆─────────────────────────────────────☆
flyingmiao (amiao) 于 (Wed Nov 12 13:14:03 2008) 提到:
【 在 CNLAS 的大作中提到: 】
: 比较交换...[esi]的值也就是a的值不停的0和0xffffffffffffffff之间交换...
: 而且用lock前缀保持原子...
: 变量a也是volatile的
: ...................
嗯,代码我看懂了。不明白为什么,双核会破坏原子性么。
☆─────────────────────────────────────☆
rebirthatsix (茫犭者-算法盲) 于 (Wed Nov 12 13:19:18 2008) 提到:
t=a;
这条不是原子操作
一个long long是分两次mov的。。。如果这期间交换了。。恩
☆─────────────────────────────────────☆
windam (棒棒糖) 于 (Wed Nov 12 13:29:51 2008) 提到:
re mz。。。
cmpxchg8b 是将eax和edx中的值与指定内存地址的8个字节进行交换。。。
p.s.
顺便还搜到一个intel设计的bug: lock cmpxchg8b eax
☆─────────────────────────────────────☆
rebirthatsix (茫犭者-算法盲) 于 (Wed Nov 12 13:30:58 2008) 提到:
【 在 windam 的大作中提到: 】
: re mz。。。
: cmpxchg8b 是将eax和edx中的值与指定内存地址的8个字节进行交换。。。
也不是单纯交换
如果相等,就把ecx:ebx的值mov进去,不等就把edx:eax的值mov进去
☆─────────────────────────────────────☆
CNLAS (愛すべきもの) 于 (Wed Nov 12 13:48:07 2008) 提到:
不等是把操作数的值mov给edx:eax
你们把答案都说了后面的人不就没得玩了么...
【 在 rebirthatsix 的大作中提到: 】
: 也不是单纯交换
: 如果相等,就把ecx:ebx的值mov进去,不等就把edx:eax的值mov进去
☆─────────────────────────────────────☆
windam (棒棒糖) 于 (Wed Nov 12 13:50:55 2008) 提到:
【 在 rebirthatsix 的大作中提到: 】
: 也不是单纯交换
: 如果相等,就把ecx:ebx的值mov进去,不等就把edx:eax的值mov进去
嗯嗯……= =
没仔细看文档就想当然了……
正确的含义是如果相等就mov ECX:EBX ,不等就不mov……= =b
CMPXCHG8B: Compare and Exchange Eight Bytes
CMPXCHG8B mem ; 0F C7 /1 [PENT]
This is a larger and more unwieldy version of CMPXCHG: it compares the 64-bit (eight-byte) value stored at [mem] with the value in EDX:EAX. If they are equal, it sets the zero flag and stores ECX:EBX into the memory area. If they are unequal, it clears the zero flag and leaves the memory area untouched.
☆─────────────────────────────────────☆
CNLAS (愛すべきもの) 于 (Wed Nov 12 14:04:44 2008) 提到:
你那资料没说清楚...Intel官方资料如下:
Compare EDX:EAX with m64. If equal, set ZF and load
ECX:EBX into m64. Else, clear ZF and load m64 into
EDX:EAX.
Intel Architecture Compatibility
This instruction is not supported on Intel processors earlier than the Pentium® processors.
Operation
IF (EDX:EAX = DEST)
ZF ← 1
DEST ← ECX:EBX
ELSE
ZF ← 0
EDX:EAX ← DEST
【 在 windam 的大作中提到: 】
: 嗯嗯……= =
: 没仔细看文档就想当然了……
: 正确的含义是如果相等就mov ECX:EBX ,不等就不mov……= =b
: ...................
☆─────────────────────────────────────☆
flyingmiao (amiao) 于 (Wed Nov 12 18:58:50 2008) 提到:
好久没看过汇编了。。。
☆─────────────────────────────────────☆
flyingkisser (齐天大猫) 于 (Wed Nov 12 19:01:41 2008) 提到:
re
【 在 rebirthatsix (茫犭者-算法盲) 的大作中提到: 】
: t=a;
: 这条不是原子操作
: 一个long long是分两次mov的。。。如果这期间交换了。。恩
: ...................
☆─────────────────────────────────────☆
coolwc (小包) 于 (Tue Nov 25 03:00:35 2008) 提到:
跟魔术的原理一样 弄几个花哨让观众以为调换发生在那里 其实在就在你眼皮底下把东西换了 转移注意力的效果
这是一条镜像帖。来源:北邮人论坛 / soft-design / #35714同步于 2009/9/21
该镜像源已超过 30 天没有更新,可能在源站已被删除。
SoftDesign机器人发帖
[合集] 一个有意思的问题,关于内存操作同步的
FadeToBlack
2009/9/21镜像同步0 回复
订阅后,新回复会通过你的通知中心匿名送达。
0 条回复
暂无回复 · 你可以订阅本帖等待新回复。