Inline assembler в Crystal

До меня доходили слухи, о том, что якобы в Crystal нет inline ассемблера.
Однако же это не так.


def add(a, b)
    asm("
        movl ($0), %eax
        addl ($1), %eax
        movl %eax, ($0)
    " :: "r"(pointerof(a)),"r"(pointerof(b)))
    a
end

x=12_i32
y=14_i32

puts add(x,y)


Есть только одна проблема: в AT&T ассемблере символ "$" вообще-то используется в качестве отличительного_префикса/сигила для констант. А здесь, как нетрудно заметить, $N — это ни что иное, как позиционный аргумент в блоке asm. И да, не спрашивайте меня, что ещё «r»(a) и странное "::" — сам теряюсь в догадках, но очевидно, что :: отделяет аргументы от кода в блоке asm, а «r»(something) собственно отвечает за определение позиционных $N, каждый из которых будет равен своему something. Сакральное знание о том, как использовать блоки asm, почёрпнуто мной отсюда: github.com/crystal-lang/crystal/blob/e2a1389e8165fb097c785524337d7bb7b550a086/src/fiber.cr#L10

0 комментариев