为什么运行后添加了syscall __NR_lchown注册?
Why is syscall __NR_lchown added to register after operation?
我在 GDB 中注意到,在我调用 __NR_write 操作之后,紧接着 __NR_lchown 系统调用号 (16) 被传递到 rax 寄存器。我得到的代码是:
.data
BemVindo: .ascii "Seja bem vindo!\n"
Digite: .ascii "Digite alguma coisa\n"
_start:
mov , %rax
mov , %rbx
mov $BemVindo, %rcx
mov , %rdx
int [=11=]x80
mov , %rax # had to add this line because I was assuming that value 4 was still there in the register
mov $Digite, %rcx
mov , %rdx
int [=11=]x80
根据我的 unistd.h
:
#define __NR_write 4
#define __NR_lchown 16
所以,因为我在 linux 我假设这个 lchown 一定与命令 chown 有关,对吗?无论如何,问题是,为什么在我调用操作后立即加载值 16?
Linux 上的系统调用遵循它们自己的 "calling convention",就像 C 函数一样。您的代码使用的 int [=10=]x80
系统调用接口遵循 32 位 x86 系统调用约定。值得注意的是,在这个约定中,系统调用的 return 值在 EAX 中被 returned。 write
系统调用的 return 值是写入文件的字节数,因此毫不奇怪,EAX 会更改为您正在写入的字符串的长度。我相信所有其他寄存器都被保留了下来。
请注意,在 64 位代码中,您应该使用 64 位 x86 系统调用接口而不是 32 位系统调用接口。 32 位接口仅使用 32 位寄存器,因此如果您尝试显示的字符串不在前 4GB 内存中,您的程序将失败。 64 位接口与 32 位接口具有不同的系统调用号,使用不同的寄存器来传递参数并使用 SYSCALL 指令而不是 INT。
我在 GDB 中注意到,在我调用 __NR_write 操作之后,紧接着 __NR_lchown 系统调用号 (16) 被传递到 rax 寄存器。我得到的代码是:
.data
BemVindo: .ascii "Seja bem vindo!\n"
Digite: .ascii "Digite alguma coisa\n"
_start:
mov , %rax
mov , %rbx
mov $BemVindo, %rcx
mov , %rdx
int [=11=]x80
mov , %rax # had to add this line because I was assuming that value 4 was still there in the register
mov $Digite, %rcx
mov , %rdx
int [=11=]x80
根据我的 unistd.h
:
#define __NR_write 4
#define __NR_lchown 16
所以,因为我在 linux 我假设这个 lchown 一定与命令 chown 有关,对吗?无论如何,问题是,为什么在我调用操作后立即加载值 16?
Linux 上的系统调用遵循它们自己的 "calling convention",就像 C 函数一样。您的代码使用的 int [=10=]x80
系统调用接口遵循 32 位 x86 系统调用约定。值得注意的是,在这个约定中,系统调用的 return 值在 EAX 中被 returned。 write
系统调用的 return 值是写入文件的字节数,因此毫不奇怪,EAX 会更改为您正在写入的字符串的长度。我相信所有其他寄存器都被保留了下来。
请注意,在 64 位代码中,您应该使用 64 位 x86 系统调用接口而不是 32 位系统调用接口。 32 位接口仅使用 32 位寄存器,因此如果您尝试显示的字符串不在前 4GB 内存中,您的程序将失败。 64 位接口与 32 位接口具有不同的系统调用号,使用不同的寄存器来传递参数并使用 SYSCALL 指令而不是 INT。