英文:
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=pascal
、owcc -mregparm=0 -mabi=fortran
、owcc -mregparm=0 -mabi=watcall
、owcc -mregparm=0
时,将在 EDX:EAX 中返回双精度值。 - 使用
owcc -mregparm=0 -mabi=cdecl
、owcc -mregparm=0 -mabi=stdcall
、owcc -mregparm=0 -mabi=fastcall
、owcc -mregparm=0 -mabi=syscall
、owcc -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=...
andowcc =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 thewcc386 -ec...
flag, e.g.owcc -mabi=cdecl
is the same aswcc386 -ecc
. - The
owcc -mregparm=...
flag corresponds to the undocumented (!)wcc386 -3...
flag, e.g.owcc -mregparm=0
is the same aswcc386 -3s
, andowcc -mregparm=3
is the same aswcc386 -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 withowcc -mregparm=3 -mabi=...
(any-mabi=...
value).
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论