Документация по системным вызовам для int80

Я изучаю ассемблер x86, и мне интересно, может ли кто-нибудь помочь мне понять, почему документация говорит мне совсем другое, чем то, что я вижу на практике?

Чтобы вызвать системный вызов, я используюint 80hпрограммное прерывание. Я поместил аргументы в первые три регистра вrbx,rcx, регистры и номер системного вызова вrax. И это работает, например, работает системный вызов чтения, и я вижу, что данные перемещаются в нужное место в памяти. Однако если я прочитаюman syscallон говорит, что я должен передать аргументы системному вызовуrdi,rsi,rdx,r10,r8,r9в этом порядке от 1 до 6 для x86_64. Это не работает, и это кажется немного безумием: я видел в Интернете несколько ресурсов, предлагающих одни и те же регистры для аргументов системного вызова. Это просто ошибка в документации?

Тот же вопрос для номеров системных вызовов. В сети советуют посмотреть/usr/include/x86_64-linux-gnu/asm/unistd_64.hно там число для чтения равно 0, и оно не работает, использование 3, как предлагает книга, работает, почему?

1 ответ

Хорошо, я понял это. Опубликую ответ здесь на случай, если у кого-то возникнет аналогичный вопрос, прочитав книгу Джеффа Дантеманна об ассемблере.

Таким образом, хотя вы можете перевести ассемблер для 64-битной версии с помощью NASM, конкретная инструкцияint 080hкаким-то образом, кажется, вызывает 32-битный режим. Не уверен, как регистры R можно использовать в 32-битном режиме, но, видимо, либо они могут, либо какой-то другой механизм интерпретирует его как 32-битную программу. Вот почему номера системных вызовов совершенно разные (они указаны в/usr/include/x86_64-linux-gnu/asm/unistd_32.h). Таким образом, выход программы — №1 в 32-разрядной версии и №60 в 64-разрядной версии.

Вместо этого следует использоватьsyscallинструкция без каких-либо аргументов. Тогда все в документации будет правильно и работать. Соглашение об именовании цепей странно, начиная с a, b, c, d, но его можно как-то объяснить.rdi,rsi,rdxэто регистры 6-5-4, поэтому в основном обратный порядок, регистрrcxуничтожается после системного вызова (так сказано в документации иr11тоже), поэтому тогда он заменяется наr10а затем с самого начала используются другие регистры R.

Другие вопросы по тегам