ARMv8 Assembly, как преобразовать целочисленное значение в значение с плавающей запятой и как его распечатать?

Когда я пытаюсь преобразовать целое число в число с плавающей запятой и распечатать его, значение, хранящееся в этом регистре, становится 0,000000.

outI: .string "%d\n"
outF: .string "%f\n"

      mov        x20,      160
            
      mov        x1,       x20
      ldr        x0,       =outI
      bl         printf
            
      scvtf      s20,      x20      //cast x20 to float
            
      fmov       s0,       s20
      ldr        x0,       =outF
      bl         printf

Когда я пытаюсь запустить приведенный выше код, выводится следующее значение:

160
0.000000

Я дал неправильную инструкцию по печати?


person Z Han    schedule 08.12.2020    source источник
comment
Зайдите в отладчик и посмотрите, что эта инструкция делает в регистрах.   -  person Michael Dorgan    schedule 08.12.2020


Ответы (1)


Спецификатор формата %f для printf ожидает аргумент типа double, но, передавая значение с плавающей запятой одинарной точности в s0, вы фактически передаете вместо этого float.

(Фактически, вариативные функции, такие как printf, никогда не могут принимать аргумент типа float. Если вы попытаетесь передать аргумент float в printf из кода C в C, он будет неявно повышен до double, но, конечно, сборка не сделает этого за вас.)

Поэтому вам нужно вместо этого получить значение с плавающей запятой двойной точности в d0. Если у вас уже есть число с плавающей запятой одинарной точности в s20, то самый простой подход - заменить ваш fmov s0, s20 на fcvt d0, s20, чтобы преобразовать его в двойную точность.

person Nate Eldredge    schedule 09.12.2020