求大神帮忙看看内联汇编
有一个gcc下AT$T格式的内联汇编函数,就几行,要转到windows下masm格式的,实现的是
compare-and-swap的一个基本操作,求大神帮忙看看,感激不尽!!
inline bool CAS(long *ptr, long oldv, long newv)
{
unsigned char ret;
/* Note that sete sets a 'byte' not the word */
__asm__ __volatile__ ( // AT&T assembly
" lock\n"
" cmpxchgq %2,%1\n"
" sete %0\n"
: "=q" (ret), "=m" (*ptr)
: "r" (newv), "m" (*ptr), "a" (oldv)
: "memory");
return ret;
}
[解决办法]
这是GCC 中C内嵌汇编:
__asm__ __volatile__ ( // AT&T assembly
" lock\n"
" cmpxchgq %2,%1\n"
" sete %0\n"
: "=q" (ret), "=m" (*ptr)
: "r" (newv), "m" (*ptr), "a" (oldv)
: "memory");
"memory"的意思是通知编译器,内存布局发生变化了,常发生在基址发生变化时使用。%0 = ret %1=*ptr %2=newv 以上三个都是C中的局存变量。至于指令lock cmpxchgg sete是什么意思,我就不清楚了,我是做ARM的对intel汇编不太了解
[解决办法]
sete 设置ret=ZF,ZF是0标记位
CMPXCHG CX,DX
如果指令执行前 (AX)=2300H,(CX)=2300H.(DX)=2400H
则指令执行后 因(CX)=(AX),故(CX)=2400H,ZF=1
如果指令执行前(AX)=2500H,(CX)=2300H,(DX)=2400H
则指令执行后因(CX)!=(AX),故(CX)=2300H,ZF=0
结合汇编代码应该是EAX = oldv
cmpxchgq %2,%1
%0 = ret %1=*ptr %2=newv
结合上面说明如果newv = oldv 则newv=*ptr ZF=1
如果newv !=oldv 则EAX=*ptr ZF=0
同时将ZF的值返回