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

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

Для выполнения арифметических действий над числами с плавающей точкой расширения SSE предоставляет ряд инструкций:

  • addss и addsd: сложение

  • subss и subsd: вычитание

  • mulss и mulsd: умножение

  • divss и divsd: деление

  • minss и minsd: вычисляют минимальное значение двух операндов, сохраняя минимальное значение в первом операнде.

  • maxss и maxsd: вычисляют максимальное значение двух операндов, сохраняя минимальное значение в первом операнде.

  • sqrtss и sqrtsd: вычисляют квадратный корень второго операнда и сохраняют результат в первый операнд

  • rcpss и rcpsd: вычисляют обратное значение второго операнда, сохраняя результат в первый операнд

  • rsqrtss и rsqrtsd: вычисляют обратное значение квадратного корня второго операнда, сохраняя результат в первый операнд

Инструкции, которые оканчиваются на ss, предназначены для 32-разрядных чисел с плавающей точкой (ss - сокращение от "scalar single"). Инструкции, которые оканчиваются на sd, предназначены для 64-разрядных чисел с плавающей точкой (sd - сокращение от "scalar double"). Общий синтаксис инструкций:

addss xmmn, xmmn
addss xmmn, mem32
addsd xmmn, xmmn
addsd xmmn, mem64

subss xmmn, xmmn
subss xmmn, mem32
subsd xmmn, xmmn
subsd xmmn, mem64

mulss xmmn, xmmn
mulss xmmn, mem32
mulsd xmmn, xmmn
mulsd xmmn, mem64

divss xmmn, xmmn
divss xmmn, mem32
divsd xmmn, xmmn
divsd xmmn, mem64

minss xmmn, xmmn
minss xmmn, mem32
minsd xmmn, xmmn
minsd xmmn, mem64

maxss xmmn, xmmn
maxss xmmn, mem32
maxsd xmmn, xmmn
maxsd xmmn, mem64

sqrtss xmmn, xmmn
sqrtss xmmn, mem32
sqrtsd xmmn, xmmn
sqrtsd xmmn, mem64

rcpss xmmn, xmmn
rcpss xmmn, mem32

rsqrtss xmmn, xmmn
rsqrtss xmmn, mem32

Первый операнд (куда помещается результат операции) всегда должен быть регистром XMM. Например, сложим два числа в программе на Linux:

global _start

section .data
num0 dq 3.4
num1 dq 6.6

section .text
_start:
    movsd xmm0, [num0]       ; помещаем в xmm0 число num0
    movsd xmm1, [num1]      ; помещаем в xmm1 число num1
    addsd xmm0, xmm1      ; xmm0 = xmm0 + xmm1
    cvtsd2si rdi, xmm0     ; из xmm0 преобразуем в целое число и помещаем в rdi

    mov rax, 60
    syscall

В данном случае складываем два числа типа qword - num1 и num2, которые предварительно загружаются в регистры xmm0 и xmm1. После сложения результат помещается в регистр xmm0, а затем конвертируется в целое число и помещается в регистр rdi. Таким образом, в регистре rdi в итоге окажется число 10.

Аналогичная программа для Windows:

global _start

section .data
num0 dq 3.4
num1 dq 6.6

section .text
_start:
    movsd xmm0, [rel num0]       ; помещаем в xmm0 число num0
    movsd xmm1, [rel num1]      ; помещаем в xmm1 число num1
    addsd xmm0, xmm1      ; xmm0 = xmm0 + xmm1
    cvtsd2si rax, xmm0     ; из xmm0 преобразуем в целое число и помещаем в rax
    ret
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850