我正在尝试使用lock cmpxchg16b指令进行原子比较并在C中的外部函数中进行交换。 对函数的调用有3个128位对象,其中我要比较前2个,如果它们彼此相等则替换为第3个。
这些是我收集的参数:
rdi:旧状态
rsi:cur status
rdx:mod status
现在,我想要做的是将rdi(不应该有下半部分吗?)加载到rax中,并将此状态的后半部分加载到rdx中。 (RDI + 8?)
如果我正在做的事情是正确的那么rdx将与rsi和rax与rsi + 8进行比较
lock cmpxchg16b (%rsi)
正确?因为它是小端的
但是如何将rdi移动到rdx:rax? 我试过这个:
movq (%rdi), %rdx
和
movq %rdi, %rdx
但我似乎无法让它发挥作用,它总是喷出它们即使用相同的物体运行两次也不相等。
现在全功能:
my_cmpr_swap:
#save rbx as we need the register
pushq %rbx
# set up registers rdx:rax
movq %rdx, (%rdi)
#compare-swap
lock cmpxchg16b (%rsi)
#return 1 if success, 0 if not
jz success
movq $0,%rax
jmp end
success:
movq $1,%rax
end:
popq %rbx
ret
答案 0 :(得分:-1)
此答案假设您通过引用传递旧值和新值。
my_cmpr_swap:
#save rbx as we need the register
pushq %rbx
# set up registers rcx:rbx
movq (%rdx), %rbx
movq 8(%rdx), %rcx
# set up registers rdx:rax
movq (%rdi), %rax
movq 8(%rdi), %rdx
#compare-swap
lock cmpxchg16b (%rsi)
#return 1 if success, 0 if not
jz success
# store updated rdx:rax
movq %rax, (%rdi)
movq %rdx, 8(%rdi)
movq $0,%rax
jmp end
success:
movq $1,%rax
end:
popq %rbx
ret
答案 1 :(得分:-1)
此答案假设您按值传递旧值和新值。
my_cmpr_swap:
#save rbx as we need the register
pushq %rbx
mov %rdx, %r10
# set up registers rcx:rbx
movq %rcx, %rbx
movq %r8, %rcx
# set up registers rdx:rax
movq %rdi, %rax
movq %rsi, %rdx
#compare-swap
lock cmpxchg16b (%r10)
#return 1 if success, 0 if not
jz success
movq $0,%rax
jmp end
success:
movq $1,%rax
end:
popq %rbx
ret