2017-02-02 18 views
0

В GDB я заметил, что после того, как я вызываю операцию __NR_write, сразу же после этого в регистр rax передается номер sysall __NR_lchown (16). Код, который я получил это:Почему syscall __NR_lchown добавлен в регистр после операции?

.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 должен иметь что-то делать с правом команды Чаун? Во всяком случае, вопрос в том, почему значение 16 загружается сразу после вызова операции?

ответ

4

Системные вызовы в Linux следуют их собственным «вызовам», как и функции C. Интерфейс системного вызова int $0x80, используемый вашим кодом, соответствует 32-битовому соглашению по системному вызову x86. Примечательно, что в этом соглашении возвращаемое значение системного вызова возвращается в EAX. Возвращаемое значение системного вызова write - это количество байтов, записанных в файл, поэтому неудивительно, что EAX изменяется на длину строки, которую вы пишете. Я считаю, что все остальные регистры сохранены.

Обратите внимание, что в 64-битном коде вы должны использовать 64-разрядный интерфейс системного вызова x86 вместо 32-разрядного. 32-битный интерфейс использует только 32-разрядные регистры, поэтому ваша программа не сработает, если строки, которые вы пытаетесь отобразить, не находятся в первых 4 ГБ памяти. 64-битный интерфейс имеет разные номера системных вызовов, чем 32-битный интерфейс, использует разные регистры для передачи аргументов и использует инструкцию SYSCALL вместо INT.

 Смежные вопросы

  • Нет связанных вопросов^_^