Gcc 如何在FreeBSD的内联程序集中调用gettimeofday系统调用?
我正在尝试使用FreeBSD 5.2.1 32位中的系统调用和内联汇编获取当前时间 我的问题是,我很难将所需的结构作为参数传递给函数,从而导致错误: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_
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");