Go Assembly by Example: Sync Atomic

This example is taken from the sync/atomic package which provides low-level atomic memory primitives. The swap operation, implemented by the SwapT functions, is the atomic equivalent of

old = *addr
*addr = new
return old
package atomic
import (
    "unsafe"
)

SwapInt32 atomically stores new into *addr and returns the previous *addr value.

func SwapInt32(addr *int32, new int32) (old int32)
#include "textflag.h"
TEXT ·SwapInt32(SB),NOSPLIT,$0-20
	JMP	·SwapUint32(SB)
TEXT ·SwapUint32(SB),NOSPLIT,$0-20
	MOVQ	addr+0(FP), BP
	MOVL	new+8(FP), AX

The XCHGL instruction is not vulnerable to a Write-After-Read as the bus is locked for the duration of the exchange.

	XCHGL	AX, 0(BP)
	MOVL	AX, old+16(FP)
	RET

Next example: Aes.