【发布时间】:2018-09-24 02:35:06
【问题描述】:
我正在尝试使用 lock cmpxchg16b 指令进行原子比较并在 C 中交换外部函数。 对函数的调用有 3 128 位对象,我想比较前 2 个对象,如果它们相等则替换为第三个对象。
这些是我收集的参数:
rdi:旧状态
rsi: 当前状态
rdx: 模组状态
现在,我要做的是将 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
【问题讨论】:
-
你没有提到 rbx 和 rcx,cmpxchg16b 也用。我认为您需要重新阅读说明说明。另外,请发布您的完整功能,而不是摘录。只有几行。
-
@prl rcx:rbx 被复制到您指定的寄存器中(这里是 rsi 和 rsi+8),如果比较成功,是的,但我不太关心,直到我真正得到 rdx :rax 设置为正确比较。我现在已经编辑了完整的功能。
-
您谈论设置
rdx:rax,但您没有设置“rax”的代码。 -
@RaymondChen 我没有,不,因为在四处搜索之后,我似乎仍然找不到要为 rdi 的后半部分引用哪个寄存器,这会很好,rdx 和然后 rdi 会转到 rax。
-
不清楚您所说的“rdi 的后半部分”是什么意思。 rdi 是一个 64 位寄存器。它的后半部分不包含其他 64 位。还是 rdi 是一个指向 128 位值的指针?
标签: assembly x86-64 cpu-registers