请问这段 Linux x64 syscall __NR_exit 给出的 exitcode 为什么不对?

这是一段 C 中直接调用 ASM 的代码:

typedef unsigned long long int uint64_t;

void _start() {
    uint64_t ret = (uint64_t) 1;
    asm(
        "mov $60, %%rax;"  // __NR_exit
        "mov %0, %%rdi;"
        "syscall"
        :
        : "r"(ret)
        :
    );
}

在 Ubuntu 16.04 x64 中我这么编译和运行它:

$ gcc -nostdinc -nostdlib start.c && (./a.out ; echo $?)
60

这很奇怪,因为我为其指定的 exitcode 是 1。请问这段代码哪里有问题吗?谢谢!

我参考的 __NR_exit 手册是 http://blog.rchapman.org/post...

阅读 2.5k
1 个回答

问题解决了。问题出自我没有在 asm() 的第四个域里声明 rax 会 changed,导致 %0 直接被存到了 rax 里。

正确的代码如下:

void _start() {
    int ret = 2;
    asm(
        "mov $60, %%rax;"  // __NR_exit
        "mov %0, %%edi;"   // param 1
        "syscall"
        :
        : "r"(ret)
        : "rax", "rdi"
    );
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏