【问题标题】:How to call gettimeofday syscall in inline assembly in FreeBSD?如何在 FreeBSD 的内联汇编中调用 gettimeofday 系统调用?
【发布时间】:2020-08-28 21:42:04
【问题描述】:

我正在尝试在 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");

我试图从这两个例子中获得灵感,但我无法让它发挥作用link1link2

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

我愿意使用clock_gettime 系统调用,但除此之外我真的很想使用内联汇编系统调用来获得它。

【问题讨论】:

  • 32 位模式与int $0x80? FreeBSD 不是在 32 位模式下在堆栈上传递系统调用参数吗?
  • 忘记指定了,但我的 FreeBSD 是 32 位 (i386)。
  • 您收到特定错误的原因是struct timezone 包含两个ints,这意味着zone 太大而无法容纳esi。我假设time_tsuseconds_t 也是ints 或更大,这意味着val 同样太大而无法容纳edi。根本问题在于,这不是您在 x86 FreeBSD 调用约定中将参数传递给系统调用的方式。
  • @PeterCordes 我说是的,它使用堆栈作为 32 位代码中的参数,并且它需要一个额外的虚拟参数。它不采用 32 位代码的寄存器中的值。
  • 我想您使用几乎可以投票的版本是有充分理由的......?

标签: gcc x86 system-calls freebsd inline-assembly


【解决方案1】:

感谢 cmets 的所有帮助。

解决的问题是:

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

代码:

#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");

E:根据评论建议优化代码。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2015-04-30
  • 2023-04-09
  • 2016-01-16
  • 2014-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多