我试图编写一个简单的接口来原子地增加一些值。我试着做以下工作(用C)

void foo()
{
    int counter = 0;
    assembly_xadd(&counter);
    printf("counter is %d\n");
}

计数器为0
这是我在程序集中的代码,我不确定是否正确使用了xadd:
.global assembly_xadd

assembly_xadd:

    PUSHL %ebp
    MOVL %esp,%ebp
    PUSHL %edi

    MOVL $0x1,%eax
    MOVL 0x8(%ebp),%edi
    XADDL  %edi,%eax

    MOVL %edi,%eax

    POPL %edi
    MOVL %ebp,%esp
    POPL %ebp
    RET

最佳答案

你想要的是XADDL %eax, (%edi)。记住,使用gas语法,目的地始终是第二个值,并且您希望更改地址%edi处的内存。而是将一个添加到地址%edi并将其存储在%eax中。在genearl中,xadd有两个寄存器是无用的(原子内存访问方式),因为寄存器操作总是原子的。
使用MOVL 0x8(%ebp),%edi所做的是将32位整数的地址移动到%edi。另外,如果你想返回原始值,这就是我假设的MOVL %edi,%eax的目的,你不应该做MOVL %edi,%eax%eax已包含先前的值(%edi)

关于c - 如何使用XADD增加内存中的值?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14823861/

10-11 16:57