LINUX.ORG.RU

Скопипастил тему float в assembler

 


0

1

Чуваки, лазил по форумам, и наткнулся на тему float в gas. Тема есть, но ответов в ней нет. Видимо так бывает, что люди знают не все.

И я такой: стопе! Могу выглядить круто, если спрошу тут, а ответ напишу там😈

Вобщем какой то обделенный как и я задается вопросом, как кодируются числа инт в float.


section .data
frm: .asciz "%.2f"
section .text

global main
main:

push %rbp
mov %rsp, %rbp

mov flt:(%rip), %ebx
mov %ebx, -4%(%rbp)

cvtss2sd -4(%rbp), %xmm0
lea frm(%rip), %rdi
mov $2, %eax
call printf


flt: . long 1066192077





leave
ret

Чуваки, реально непонятно как и что изменить в .long 1066192077 чтобы вывелось на экран 9,9

Как они представляются? Сколько и какие пары чисел из 1066192077 отвечают за целую часть, а какие пары или пара, отвечает за дробную?


Читай про представление чисел в IEEE 754 https://www.softelectro.ru/ieee754.html и сделай такое число, чтоб мантисса и экспонента там была тем что надо.

И нафига это вообще, если есть специальные директивы для флоатов? https://sourceware.org/binutils/docs/as/i386_002dFloat.html

SZT ★★★★★ ()
Последнее исправление: SZT (всего исправлений: 1)
Ответ на: комментарий от LGH

Ты это руками на тетрадке в клеточку расчитывать собрался? Или компьютерная программа тоже подойдет? https://wandbox.org/permlink/nSOj0YUFradrBkg6

Руками перевести конечно же тоже можно, но это долго описывать, мантиссы там всякие экспонетны, знаковые биты, к тому же это зависит от того, какой там endian. Нафига это тебе?

SZT ★★★★★ ()

Тег ассемблер здесь явно лишний.

Как и ассемблерный код.

#include <stdio.h>

int main ()
{
    float x =  9.9;
    unsigned int i = 0xbed113c8;
    printf ("%.1f (float) = %.8x (uint)\n", x, x);
    printf ("%.8x (uint) = %.1f (float)\n", i, i);
    return 0;
}
sh-5.0$ gcc float.c -o float
sh-5.0$ ./float 
9.9 (float) = dac3ebe8 (uint)
bed113c8 (uint) = 9.9 (float)
sh-5.0$ 

https://en.wikipedia.org/wiki/IEEE_754

luke ★★★★★ ()

Кстати, gcc генерирует подозрительно похожий на твой выхлоп для того что я накалякал в предыдущем сообщении:

    .file   "float.c"
    .text
    .section    .rodata
.LC1:
    .string "%.1f (float) = %.8x (uint)\n"
.LC2:
    .string "%.8x (uint) = %.1f (float)\n"
    .text
    .globl  main
    .type   main, @function
main:
.LFB0:
    .cfi_startproc
    pushq   %rbp
    .cfi_def_cfa_offset 16 
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    subq    $16, %rsp
    movss   .LC0(%rip), %xmm0
    movss   %xmm0, -8(%rbp)
    movl    $-1093594168, -4(%rbp)
    cvtss2sd    -8(%rbp), %xmm1
    cvtss2sd    -8(%rbp), %xmm0
    leaq    .LC1(%rip), %rdi
    movl    $2, %eax
    call    printf@PLT
    movl    -4(%rbp), %edx
    movl    -4(%rbp), %eax
    movl    %eax, %esi
    leaq    .LC2(%rip), %rdi
    movl    $0, %eax
    call    printf@PLT
    movl    $0, %eax
    leave
luke ★★★★★ ()
Ответ на: комментарий от luke

Вы непоняли наверное....



Судя по формуле .long 80000001 должно было вывести отрицательное число.

Не получается так.

Где тут мантисса? В каких битах? 8 в 8xxxxxxx отвечает за знак. Все остальное не работает
Вы знаете как рассчитать?

LGH ()
Ответ на: комментарий от SZT

Не, надо понять, как рассчитывать…. где в .long xxxxxxxxxxx мантисса, а где экспонента?

Вот есть у нас число 5.5 в десятичной… что надо с ним сделать, чтобы оно преобразовалось в .long xxxxxxxxxxx ? Пригодное для вывода в printf?

LGH ()
Ответ на: комментарий от ox55ff

Этоя понял….
Сомневался что примет это в такой форме.

Приняло. Спасибо. Когда буду выеживаться на другом форуме, то обязательно упомяну ваш вклад, то есть вклад LORa в решение данной задачи.

LGH ()
Ответ на: комментарий от LGH

Про соглашение вызовов прочитай, ключевые слова «x86 calling conventions», «System V ABI». Оно из xmm0 его и читает, это норма.

https://github.com/hjl-tools/x86-psABI/wiki/x86-64-psABI-1.0.pdf

SZT ★★★★★ ()
Последнее исправление: SZT (всего исправлений: 2)