Для выполнения деления в ассемблере ARM64 применяются две инструкции:
SDIV: деление со знаком
UDIV: деление без знака
Обе инструкции имеют аналогичный синтаксис:
SDIV Xd, Xn, Xm UDIV Xd, Xn, Xm
Регистр Xn представляет делимое, регистр Xm - делитель, а в регистр Xd помещается результат деления. В качестве регистров можно использовать как 64-разрядные, так и 32-разрядные.
Стоит учитывать, что эти инструкции не устанавливают условные флаги. Кроме того, результат - всегда целая часть, а получить остаток от деления мы не можем. И также, как и в стандартной математике, на ноль делить нельзя - при делении на ноль генерируется ошибка.
Примеры инструкций
MOV X2, #45 MOV X3, #5 SDIV X0, X2, X3 // X0=X2/X3 = 45/5 = 9 MOV X2, #49 MOV X3, #5 UDIV X0, X2, X3 // X0=X2/X3 = 49/5 = 9
Инструкция SDIV учитывает старший разряд числа и интерпретирует его как знак числа: если этот разряд равен 1, то число отрицательное, если 0 - положительное:
MOV W2, #0xf0000000 MOV W3, #2 // число в W0 интерпретируется как положительное UDIV W0, W2, W3 // W0=W2/W3 = 0xf0000000/2 = 0x78000000
В этом случае фактически только старший байт - 0xF0 (0b11110000) делится на 2. В итоге мы получим 0x78 (0b01111000)
Теперь разделим те же самые числа с помощью SDIV:
MOV W2, #0xf0000000 MOV W3, #2 // число в W0 интерпретируется как отрицательное SDIV W0, W2, W3 // W0=W2/W3 = 0xf0000000/2 = 0xf8000000
Формально в старшем байте мы получим тот же самый результат - 0x78 (0b01111000), однако поскольку число в W2 имеет старший бит равный 1 и поэтому расценивается как отрицательное, то старший бит рехультата также будет получать значение 1. То есть фактически старший байт результата равен "0b11111000" или 0xF8.