Gcc 如何在FreeBSD的内联程序集中调用gettimeofday系统调用?

Gcc 如何在FreeBSD的内联程序集中调用gettimeofday系统调用?,gcc,x86,system-calls,freebsd,inline-assembly,Gcc,X86,System Calls,Freebsd,Inline Assembly,我正在尝试使用FreeBSD 5.2.1 32位中的系统调用和内联汇编获取当前时间 我的问题是,我很难将所需的结构作为参数传递给函数,从而导致错误: error: impossible register constraint in `asm' 我当前实际运行的代码如下所示: #include <sys/syscall.h> #include <sys/time.h> struct timeval val; struct timezone zone; zone.tz_

我正在尝试使用FreeBSD 5.2.1 32位中的系统调用和内联汇编获取当前时间

我的问题是,我很难将所需的结构作为参数传递给函数,从而导致错误:

error: impossible register constraint in `asm'
我当前实际运行的代码如下所示:

#include <sys/syscall.h>
#include <sys/time.h>

struct timeval val;
struct timezone zone;

zone.tz_minuteswest = 0;
zone.tz_dsttime = 0;

long ret;

asm("int $0x80"
    : "=a"(ret)
    : "0"(SYS_gettimeofday), "D"(val), "S"(zone)
    : "memory");
#包括
#包括
结构时间值;
结构时区;
zone.tz_minuteswest=0;
zone.tzdstutime=0;
长ret;
asm(“整数$0x80”
:“=a”(ret)
:“0”(SYS_gettimeofday)、“D”(val)、“S”(zone)
:“记忆”);
我试着从这两个例子中获得灵感,但我没能成功

我管理的另一件事是调用系统调用,比如
getuid
,因为它不需要参数,直接返回值


我愿意使用
clock\u gettime
syscall,但除此之外,我真的希望使用内联程序集syscalls获得它。

感谢评论中的所有帮助

解决的问题有:

  • 传递指针而不是值
  • 使用约定传递参数(x86-32 FreeBSD)
代码:

#包括
#包括
结构时间值;
结构时区;
zone.tz_minuteswest=0;
zone.tzdstutime=0;
无符号整数ret;
挥发性物质(
“推送%3;”
“推送%2;”
“推送$0;”
“整数$0x80”
“添加$12,%%esp”
:“=a”(ret)
:“a”(SYS_gettimeofday)、“r”(&val)、“r”(&zone)
:“记忆”);

E:根据注释建议优化代码。

32位模式,带
int$0x80
?FreeBSD不是在32位模式下传递堆栈上的syscall args吗?忘记指定了,但我的FreeBSD是32位的(i386)。导致出现特定错误的原因是
struct timezone
包含两个
int
s,这意味着
zone
太大,无法放入
esi
。我假设
time\u t
suseconds\u t
也是
int
s或更大,这意味着
val
同样太大,无法放入
edi
。根本的问题是,在x86 FreeBSD调用约定中,您不是这样向系统调用传递参数的。@PeterCordes我说的是“是”,它在32位代码中使用堆栈作为参数,并且它需要额外的伪参数。它在32位代码中不接受寄存器中的值。我想您使用的版本几乎可以投票了,这是一个很好的原因…?您缺少了一个内存缓冲()。另外,您忘了添加$12,%esp来清理堆栈。内联asm语句必须使ESP保持不变。另外,您可以首先在
“a”
中询问电话号码,而无需
mov
它。
#include <sys/syscall.h>
#include <sys/time.h>

struct timeval val;
struct timezone zone;

zone.tz_minuteswest = 0;
zone.tz_dsttime = 0;

unsigned int ret;

asm volatile(
  "push %3;"
  "push %2;"
  "push $0;"
  "int $0x80"
  "add $12, %%esp"
  : "=a"(ret)
  : "a"(SYS_gettimeofday), "r"(&val), "r"(&zone)
  : "memory");