Anonymous user
Inline Assembly: Difference between revisions
→asm goto
[unchecked revision] | [unchecked revision] |
m (→asm goto) |
|||
Line 165:
</source>
One example where this
<source lang="c">
#define cmpxchg( ptr, _old, _new ) { \
volatile u32 *__ptr = (volatile u32 *)(ptr); \
u32 __ret; \
asm volatile( "lock; cmpxchgl %2,%1" \
: "=a" (__ret), "+m" (*__ptr) \
: "r" (_new), "0" (_old) \
: "memory"); \
); \
__ret; \
}
</source>
In addition to returning the current value in EAX, CMPXCHG sets the zero flag (Z) when successful. Wihtout asm gotos, your code will have to check the returned value;
this CMP instruction can be avoided as follows:
<source lang="c">
#define cmpxchg( ptr, _old, _new, fail_label ) { \
volatile u32 *__ptr = (volatile u32 *)(ptr); \
u32 __ret; \
asm volatile goto( "lock; cmpxchgl %2,%1 \t\n" \
"jnz %l[fail_label] \t\n" \
: "=a" (__ret), "+m" (*__ptr) \
: "r" (_new), "0" (_old) \
: "memory" \
: fail_label ); \
); \
__ret; \
}
</source>
This new macro could then be used as follows:
<source lang="c">
volatile Item *head;
void addItem( Item *i ) {
again:
Item *oldHead = head;
i->next = oldHead;
cmpxchg( &tail, oldHead, i, again );
}
</source>
==Intel Syntax==
|