【问题标题】:Passing float value from C program to assembler level program using only integer registers?仅使用整数寄存器将浮点值从 C 程序传递到汇编程序级程序?
【发布时间】:2019-12-02 20:50:46
【问题描述】:

对于我的课程,我们正在编写一个简单的 asm 程序(使用 C 和 AT&T x86-64),它打印整数或浮点数的所有位。我的整数部分工作正常。对于浮点部分,我的教授指示我们只使用整数寄存器传递浮点值。不太清楚为什么我们不允许使用浮点寄存器。无论如何,有没有人有关于如何去做这件事的想法?

【问题讨论】:

  • 哪个部分导致您出现问题? *(uint32_t*)&float_variable 可能不是标准 C,但无论如何 :) 当然,您也可以将其地址传递为 void*,这样就可以正常工作于整数和浮点数,并且也符合标准。
  • @Jester 使用union 使其成为标准。
  • 传递给 printf?例如,只需使用mov 将其作为整数传递给%x 转换。

标签: c assembly floating-point x86-64


【解决方案1】:

我的教授指示我们只使用整数寄存器传递浮点值。

一个简单的方法是使用memcpy()float复制到一个整数中

float f = ...;
assert(sizeof f == sizeof(uint32_t));

uint32_t u;
memcpy(&u, &f, sizeof u);
foo(u);

另一个是使用union。也许使用复合文字

void foo (uint32_t);

int main() {
  float f;
  assert(sizeof f == sizeof(uint32_t));

  //  v----------- compound literal -----------v
  foo((union { float f; uint32_t u; }) { .f = f}.u);
  //   ^------ union object ------- ^
}

两者都要求使用的整数类型和float 的大小相同。

其他问题包括确保两者的字节序正确,但通常float 和整数的字节序会匹配。

【讨论】:

  • 有趣的事实:x86-64 System V 传递 {float; uint32_t}; 的联合与传递 uint32_t 的方式相同,因此对于 printf 等可变参数函数,您可以只传递联合对象并忽略编译器警告与转化不匹配。
猜你喜欢
  • 2018-07-31
  • 2019-12-26
  • 1970-01-01
  • 1970-01-01
  • 2012-01-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-09
相关资源
最近更新 更多