我在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?
答案 0 :(得分:4)
Linux上的系统调用遵循他们自己的"调用约定"就像C函数一样。您的代码使用的int $0x80
系统调用接口遵循32位x86系统调用约定。值得注意的是,在此约定中,系统调用的返回值在EAX中返回。 write
系统调用的返回值是写入文件的字节数,因此不出所料EAX被更改为您正在编写的字符串长度。我相信所有其他寄存器都会被保留。
请注意,在64位代码中,您应该使用64位x86系统调用接口而不是32位代码。 32位接口仅使用32位寄存器,因此如果您尝试显示的字符串不在前4GB内存中,则程序将失败。 64位接口具有与32位接口不同的系统调用号,使用不同的寄存器来传递参数并使用SYSCALL指令而不是INT。