在 ASM 中为 cmpxchg16b 设置寄存器
Setting up registers for cmpxchg16b in ASM
我正在尝试使用 lock cmpxchg16b 指令在 C 语言的外部函数中进行原子比较和交换。
该函数的调用有 3 128 位对象,我想比较其中的前 2 个,如果它们相等,则替换为第三个。
这些是我收集的参数:
rdi:旧状态
rsi:当前状态
rdx: mod 状态
现在,我要做的是将 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 [=13=],%rax
jmp end
success:
movq ,%rax
end:
popq %rbx
ret
此答案假定您通过引用传递旧值和新值。
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 [=10=],%rax
jmp end
success:
movq ,%rax
end:
popq %rbx
ret
此答案假定您按值传递旧值和新值。
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 [=10=],%rax
jmp end
success:
movq ,%rax
end:
popq %rbx
ret
我正在尝试使用 lock cmpxchg16b 指令在 C 语言的外部函数中进行原子比较和交换。 该函数的调用有 3 128 位对象,我想比较其中的前 2 个,如果它们相等,则替换为第三个。
这些是我收集的参数:
rdi:旧状态
rsi:当前状态
rdx: mod 状态
现在,我要做的是将 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 [=13=],%rax
jmp end
success:
movq ,%rax
end:
popq %rbx
ret
此答案假定您通过引用传递旧值和新值。
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 [=10=],%rax
jmp end
success:
movq ,%rax
end:
popq %rbx
ret
此答案假定您按值传递旧值和新值。
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 [=10=],%rax
jmp end
success:
movq ,%rax
end:
popq %rbx
ret