在ASM中为cmpxchg16b设置寄存器

时间:2018-04-13 17:03:37

标签: assembly x86-64 cpu-registers

我正在尝试使用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

2 个答案:

答案 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