gcc - 退出系统调用的正确常量是什么?

标签 gcc assembly x86-64

我正在尝试学习 x86_64 汇编,并使用 GCC 作为我的汇编程序。我正在使用的确切命令是:

gcc -nostdlib tapydn.S -D__ASSEMBLY__

我主要使用 gcc 作为它的预处理器。这里是 tapydn.S :
.global _start

#include <asm-generic/unistd.h>

syscall=0x80

.text
_start:
    movl $__NR_exit, %eax
    movl $0x00, %ebx
    int  $syscall

这会导致段错误。我认为问题出在以下行:
 movl $__NR_exit, %eax

我用了__NR_exit因为它比一些神奇的数字更具描述性。但是,看来我对它的使用是不正确的。我相信是这样的,因为当我将有问题的行更改为以下内容时,它运行良好:
movl $0x01, %eax
usr/include/asm-generic/unistd.h 的内容进一步支持了这一思路。 :
#define __NR_exit 93
__SYSCALL(__NR_exit, sys_exit)

我预计 __NR_exit 的值为 1,而不是 93!显然,我误解了它的目的,因此误解了它的用法。据我所知,$0x01 让我很幸运案例工作(很像 C++ 中的未定义行为),所以我一直在挖掘......

接下来,我查找了sys_exit的定义。 .我找不到它。我尝试按如下方式使用它(有和没有前面的$):
movl $sys_exit, %eax

这不会链接:
/tmp/cc7tEUtC.o: In function `_start':
(.text+0x1): undefined reference to `sys_exit'
collect2: error: ld returned 1 exit status

我的猜测是它是其中一个系统库中的一个符号,由于我传递了-nostdlib,我没有链接它。到海湾合作委员会。如果可能的话,我想避免为一个符号链接(symbolic link)这么大的库。

为了回应 Jester 关于混合 32 位和 64 位常量的评论,我尝试使用值 0x3C按照建议:
movq $0x3C, %eax
movq $0x00, %ebx

这也导致了段错误。我也试过换掉eaxebx对于 raxrbx :
movq $0x3C, %rax
movq $0x00, %rbx

段错误仍然存​​在。

Jester 然后评论说我应该使用 syscall而不是 int $0x80 :
.global _start

#include <asm-generic/unistd.h>

.text
_start:
    movq $0x3C, %rax
    movq $0x00, %rbx
    syscall

这行得通,但后来我被告知我应该使用 rdi而不是 rbx根据 System V AMD64 ABI:
movq $0x00, %rdi

这也可以正常工作,但最终仍然使用魔数(Magic Number) 0x3C为系统调用号。

总结一下,我的问题如下:
  • __NR_exit的正确用法是什么?
  • 我应该使用什么来代替 exit 的魔数(Magic Number)系统调用?
  • 最佳答案

    获取系统调用号的正确头文件是sys/syscall.h .这些常量称为 SYS_###在哪里 ###是您感兴趣的系统调用的名称。__NR_###宏是实现细节,不应使用。根据经验,如果标识符以下划线开头,则不应使用,如果以 2 开头,则绝对不应使用。参数进入 rdi , rsi , rdx , r10 , r8 , 和 r9 .这是 Linux 的示例程序:

    #include <sys/syscall.h>
    
        .globl _start
    _start:
        mov $SYS_exit,%eax
        xor %edi,%edi
        syscall
    

    这些约定大多可移植到其他类 UNIX 操作系统。

    关于gcc - 退出系统调用的正确常量是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41915010/

    相关文章:

    gcc - 如何用gtk3编译gtk2.0程序?

    linux - 如何链接共享库的特定名称(版本)

    assembly - 错误: junk `0x7f' after expression when assembling using Gas

    assembly - memcmp 忽略奇数位置的字符

    c++ - Gcc 忽略 -Wno-unused-variable

    bash - 如何通过管道传递 gcc 或 gfortran 警告和错误

    gnu - x86-64 GNU 程序集

    c - 如果我不包含标题,为什么在调用函数之前清除 EAX?

    linux - 如何从程序集 nasm x86 linux 8086 调用 printf

    c++ - SFINAE 组装?