Арифметические операции с числами с плавающей точкой

Последнее обновление: 20.01.2023

FPU поддерживает четыре базовые арифметические операции и ряд дополнительных операций:

  • FADD: сложение двух регистров

    FADD Dd, Dn, Dm // Dd = Dn + Dm
    
  • FSUB: вычитание двух регистров

    FSUB Dd, Dn, Dm // Dd = Dn - Dm
    
  • FMUL: умножение двух регистров

    FMUL Dd, Dn, Dm // Dd = Dn * Dm
    
  • FDIV: деление двух регистров

    FDIV Dd, Dn, Dm // Dd = Dn / Dm
    
  • FMADD: умножение двух регистров с последующим сложением с третим

    FMADD Dd, Dn, Dm, Da // Dd = Da + Dm * Dn
    
  • FMSUB: умножение двух регистров с последующим вычтанием из третьего

    FMSUB Dd, Dn, Dm, Da // Dd = Da – Dm *Dn
    
  • FNEG: умножение на -1

    FNEG Dd, Dn // Dd = - Dn
    
  • FABS: абсолютное значение числа из регистра

    FABS Dd, Dn 	// Dd = абсолютное значение регистра Dn
    
  • FMAX: максимальное значение среди двух регистров

    FMAX Dd, Dn, Dm 	// Dd = Max( Dn, Dm )
    
  • FMIN: минимальное значение среди двух регистров

    FMIN Dd, Dn, Dm // Dd = Min( Dn, Dm )
    
  • FSQRT: квадратный корень

    FSQRT Dd, Dn 	// Dd = квадратный корень числа из Dn
    

Все эти операции могут принимать значения регистров H, S и D

FADD Hd, Hn, Hm // Hd = Hn + Hm
FADD Sd, Sn, Sm // Sd = Sn + Sm
FADD Dd, Dn, Dm // Dd = Dn + Dm

Для примера выполним операцию сложения, а для вывода результата воспользуемся функцией printf языка С. Пусть файл программы называется main.s и имеет следующий код:

.global main
main:
    STR LR, [SP, #-16]!
    LDR X0, =number1             // загружаем указатель на число number1
    LDR X1, =number2             // загружаем указатель на число number2
    LDR D0, [X0]                // загружаем данные по адресу из X0 в регистр D0
    LDR D1, [X1]                // загружаем данные по адресу из X1 в регистр D1
    FADD D0, D0, D1             // D0 = D0 + D1
    FMOV X1, D0                 // помещаем число double в X1 для форматированного вывода в printf
    LDR X0, =prtstr             // загружаем строку форматирования
    BL printf                   // вызываем функцию printf - выводим на консоль полученное расстояние

    MOV X0, #0      // код возврата
    LDR LR, [SP], #16
    RET
.data
    number1: .double 6.5
    number2: .double 5.6
    prtstr: .asciz "number = %f\n"

В данном случае фактически складываем два числа - number1 и number2.

Поскольку файл main.s использует функционал языка С, то скопилируем приложение с помощью компилятора gcc:

aarch64-none-linux-gnu-gcc main.s -o main -static

В итоге при выполнении программы на консоль будет выведено:

number = 12.100000
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850