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

#assembly #arm #printf #arm64 #armv8

#сборка #рука #printf #арм64 #armv8

Вопрос:

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

 outI: .string "%dn"
outF: .string "%fn"

      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
 

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

Комментарии:

1. Зайдите в отладчик и посмотрите, что эта инструкция делает в регистрах.

Ответ №1:

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

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

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