【问题标题】:Why is syscall __NR_lchown added to register after operation?为什么运行后会添加syscall __NR_lchown到寄存器?
【发布时间】:2017-06-18 23:59:15
【问题描述】:

我在 GDB 中注意到,在我调用 __NR_write 操作之后,立即将 __NR_lchown 系统调用号 (16) 传递到 rax 寄存器。我得到的代码是:

.data

BemVindo: .ascii "Seja bem vindo!\n"
Digite: .ascii "Digite alguma coisa\n"

_start:

    mov $4, %rax
    mov $1, %rbx
    mov $BemVindo, %rcx
    mov $16, %rdx
    int $0x80

    mov $4, %rax # had to add this line because I was assuming that value 4 was still there in the register
    mov $Digite, %rcx
    mov $20, %rdx
    int $0x80

据我unistd.h

#define __NR_write 4
#define __NR_lchown 16

所以,既然我在 linux 上,我认为这个 lchown 一定与命令 chown 有关系,对吧?无论如何,问题是,为什么在我调用操作后立即加载值 16?

【问题讨论】:

    标签: assembly system-calls


    【解决方案1】:

    Linux 上的系统调用遵循自己的“调用约定”,就像 C 函数一样。您的代码使用的int $0x80 系统调用接口遵循32 位x86 系统调用约定。值得注意的是,在这个约定中,系统调用的返回值在 EAX 中返回。 write 系统调用的返回值是写入文件的字节数,因此不出所料,EAX 会更改为您正在编写的字符串的长度。我相信所有其他寄存器都被保留了。

    请注意,在 64 位代码中,您应该使用 64 位 x86 系统调用接口而不是 32 位接口。 32 位接口仅使用 32 位寄存器,因此如果您尝试显示的字符串不在前 4GB 内存中,您的程序将失败。 64 位接口与 32 位接口有不同的系统调用号,使用不同的寄存器来传递参数并使用 SYSCALL 指令而不是 INT。

    【讨论】:

      猜你喜欢
      • 2021-09-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多