Документация по системным вызовам для 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.