内联汇编程序,用于调用系统调用并检索其结果

时间:2013-06-23 12:53:06

标签: c linux assembly system-calls inline-assembly

我想在程序集内联中调用系统调用(prctl)并检索系统调用的结果。但我不能让它发挥作用。

这是我正在使用的代码:

int install_filter(void)
{

   long int res  =-1; 
   void *prg_ptr  = NULL; 

  struct sock_filter filter[] = {
    BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_TRAP),
        /* If a trap is not generate, the application is killed */
        BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL),
    };
    struct sock_fprog prog = {
        .len = (unsigned short)(sizeof(filter)/sizeof(filter[0])),
        .filter = filter,
    };

  prg_ptr = &prog; 

  no_permis(); 

  __asm__ (
        "mov  %1,    %%rdx\n"
        "mov  $0x2,  %%rsi \n"
        "mov  $0x16, %%rdi \n"
        "mov  $0x9d, %%rax\n"
        "syscall\n"
        "mov %%rax, %0\n"
        : "=r"(res)
        : "r"(prg_ptr)    
        :  "%rdx", "%rsi", "%rdi", "%rax" 
        );

   if ( res < 0 ){
    perror("prctl");
    exit(EXIT_FAILURE);
    }

  return 0;
}

过滤器的地址应该是输入(prg_ptr),我想将结果保存在res中。

你能帮帮我吗?

1 个答案:

答案 0 :(得分:3)

对于内联汇编,除非必须,否则不要使用这样的movs,即使这样你也必须做丑陋的shiffling。那是因为你不知道寄存器的参数是什么。相反,你应该使用:

__asm__ __volatile__ ("syscall" : "=a"(res) : "d"(prg_ptr), "S"(0x2), "D"(0x16), "a"(0x9d) : "memory");

我还添加了__volatile__,您应该将其用于除了输出之外的副作用的任何asm,以及memory clobber(内存屏障),您应该将其用于任何带有副作用的asm - 对内存的影响或对内存访问重新排序的内容将无效。除非您知道不需要它们,否则总是将这两个用于系统调用是一种好习惯。

如果您仍然遇到问题,请使用strace观察系统调用尝试,看看出现了什么问题。