В ассемблере ARM64 имеется ряд инструкций, которые выполняют умножение с последующим сложением или вычитанием, так как сказать накапливают или аккумулируют результат. Подобные инструкции особенно полезны при работе с матрицами. Часть инструкций выполняет умножение с последующим сложением:
MADD Xd, Xn, Xm, Xa SMADDL Xd, Wn, Wm, Xa // сложение со знаком 32-разрядных регистров UMADDL Xd, Wn, Wm, Xa // сложение без знака 32-разрядных регистров
В данном случае результат инструкции будет аналогичен выражению
Xd = Xa + Xn/Wn * Xm/Wm
Другая часть инструкций выполняет умножение с последующим вычитанием:
MSUB Xd, Xn, Xm, Xa SMSUBL Xd, Wn, Wm, Xa // вычитание со знаком 32-разрядных регистров UMSUBL Xd, Wn, Wm, Xa // вычитание без знака 32-разрядных регистров
Для этих инструкций результат инструкции будет аналогичен выражению
Xd = Xa - Xn/Wn * Xm/Wm
В обоих случаях в качестве регистра Xd может выступать тот регистр Xa, в этом случае он выступает в качестве аккумулятора, который накапливает результат.
Например:
.global _start _start: MOV X1, #2 MOV X2, #3 MOV X4, #4 MADD X0, X1, X2, X4 // X0 = X1 * X2 + X4 MOV X8, #93 // завершаем программу SVC 0
Здесь инструкция MADD X0, X1, X2, X4
фактически будет эквивалентна X0 = X1 * X2 + X4
. В итоге в регистре X0 окажется число 10.
Аналогично производится умножение с вычитанием:
.global _start _start: MOV X1, #2 MOV X2, #3 MOV X4, #11 MSUB X0, X1, X2, X4 // X0 = X4 - X1 * X2 MOV X8, #93 // завершаем программу SVC 0
Здесь инструкция MSUB X0, X1, X2, X4
фактически будет эквивалентна X0 = X4 - X1 * X2
. В итоге в регистре X0 окажется число 10.