如何使OpenWatcom编译的C函数返回ST(0)中的double值?

huangapple go评论64阅读模式
英文:

How to make C function compiled by OpenWatcom return a double in ST(0)?

问题

当使用OpenWatcom C编译器为Linux i386编译时,以下C函数

```c
double retfp(void) { return 42; }

生成的代码将双精度值存储在EDX:EAX中。但是,我想将其存储在ST(0)中,就像GCC一样。在OpenWatcom中是否可以通过命令行标志实现这个目标?


<details>
<summary>英文:</summary>

The C function

```c
double retfp(void) { return 42; }

, when compiled with OpenWatcom C compiler for Linux i386:

owcc -blinux -fno-stack-check -fsigned-char -march=i386 -Os -W -Wall -Wextra -Werror -mregparm=0 -c -o retfp.owcc.obj retfp.c

has code which returns the double in EDX:EAX. However, I want to get it in ST(0) instead, like how GCC does it. Is thiss possible with OpenWatcom, maybe via a command-line flag?

答案1

得分: 2

你应该指定返回浮点值的调用约定为ST(0),例如cdecl

double __cdecl retfp(void) { return 42; }

反汇编输出:

段: _TEXT 字节 USE32 00000007 字节
0000                            _retfp:
0000  DD 05 00 00 00 00                 fld             qword ptr L$1
0006  C3                                ret
...
段: CONST DWORD USE32 00000008 字节
0000                            L$1:
0000  00 00 00 00 00 00 45 40                         ......E@

您还可以使用-mabi标志将默认调用约定指定为owcc

英文:

You should specify calling convention which returns floating point values in ST(0), for example cdecl:

double __cdecl retfp(void) {  return 42; }

Dissassembler output:

Segment: _TEXT BYTE USE32 00000007 bytes
0000                            _retfp:
0000  DD 05 00 00 00 00                 fld             qword ptr L$1
0006  C3                                ret
...
Segment: CONST DWORD USE32 00000008 bytes
0000                            L$1:
0000  00 00 00 00 00 00 45 40                         ......E@

Also you can specify default calling convention to owcc with -mabi flag.

答案2

得分: 0

TL;DR 使用 owcc -mabi=cdecl 而不是 owcc -mregparm=0

扩展 @dimich 的答案:

  • owcc -mabi=...owcc -mregparm=... 标志值 一起 确定调用约定,调用约定确定了(例如)值将在哪些寄存器中返回。
  • owcc -mabi=... 标志对应于 wcc386 -ec... 标志,例如 owcc -mabi=cdecl 相当于 wcc386 -ecc
  • owcc -mregparm=... 标志对应于未记录的 wcc386 -3... 标志,例如 owcc -mregparm=0 相当于 wcc386 -3s,而 owcc -mregparm=3 相当于 wcc386 -3r
  • 默认值是 owcc -mregparm=3 -mabi=watcall
  • 使用 owcc -mregparm=0 -mabi=pascalowcc -mregparm=0 -mabi=fortranowcc -mregparm=0 -mabi=watcallowcc -mregparm=0 时,将在 EDX:EAX 中返回双精度值。
  • 使用 owcc -mregparm=0 -mabi=cdeclowcc -mregparm=0 -mabi=stdcallowcc -mregparm=0 -mabi=fastcallowcc -mregparm=0 -mabi=syscallowcc -mregparm=3,以及 owcc -mregparm=3 -mabi=...(任何 -mabi=... 值)时,将在 ST(0) 中返回双精度值。
英文:

TL;DR Use owcc -mabi=cdecl instead of owcc -mregparm=0.

Extending the answer of @dimich:

  • The owcc -mabi=... and owcc =mregparm=... flag values together determine the calling convention, and the calling convention determines (e.g.) in which registers values are returned.
  • The owcc -mabi=... flag corresponds to the wcc386 -ec... flag, e.g. owcc -mabi=cdecl is the same as wcc386 -ecc.
  • The owcc -mregparm=... flag corresponds to the undocumented (!) wcc386 -3... flag, e.g. owcc -mregparm=0 is the same as wcc386 -3s, and owcc -mregparm=3 is the same as wcc386 -3r.
  • The default is owcc -mregparm=3 -mabi=watcall.
  • doubles are returned in EDX:EAX with owcc -mregparm=0 -mabi=pascal, owcc -mregparm=0 -mabi=fortran, owcc -mregparm=0 -mabi=watcall, owcc -mregparm=0.
  • doubles are returned in ST(0) with owcc -mregparm=0 -mabi=cdecl, owcc -mregparm=0 -mabi=stdcall, owcc -mregparm=0 -mabi=fastcall, -mregparm=0 -mabi=syscall, owcc -mregparm=3, and also with owcc -mregparm=3 -mabi=... (any -mabi=... value).

huangapple
  • 本文由 发表于 2023年5月18日 07:28:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/76276807.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定