2013-03-24 2 views
8

С MS-DOS я знаю вызов системы с использованием прерываний. В старых документах я ссылался на int 80h для вызова системных функций в Linux. Поскольку довольно давно я знаю, что int 80h устарел в пользу инструкции syscall. Но я не могу заставить его работать на моей 32-битной машине.Syscall или sysenter на 32 битах Linux?

Вопрос

ли syscall инструкция будет использоваться только на 64 битных платформ? Не использует ли 32 бит Linux syscall?

Опытный образец

На моих 32 бит Linux (Ubuntu Precise), эта программа завершается с дампом памяти:

global _start 

_start: 
     mov  eax, 4    ; 4 is write 
     mov  ebx, 1    ; 1 is stdout 
     mov  ecx, message   ; address of string 
     mov  edx, length   ; number of bytes 
     syscall 

     mov  eax, 1    ; 1 is exit 
     xor  ebx, ebx    ; return code 0 
     syscall 

message: 
     db 10,"Hello, World",10,10 
length equ $ - message 

Я попытался с sysenter вместо syscall, но он терпит крах так же.

+0

Возможный дубликат [Что лучше «int 0x80» или «syscall»?] (http://stackoverflow.com/questions/12806584/what -is-better-int-0x80-or-syscall) – Michael

+1

Существует действительно что-то связанное, [здесь] (http://stackoverflow.com/a/12806910/279335), но которое не отвечает в очередь Stion. Он говорит, что «syscall» недоступен в 32-битном режиме процессоров Intel, но ассемблер скомпилировал его в режиме 32 бит; либо утверждение неясно, либо неверно. Затем я получаю ядро-дамп из-за нелегальной инструкции, но эта инструкция доступна для всех процессоров Intel, начиная с Pentium II, а моя намного выше этого. Он упоминает 'sysenter', который я попытался с тем же результатом. Во всяком случае, я никогда не видел упоминания 'sysenter' в Linux ABI, только' int 80h' или 'syscall'. – Hibou57

+2

Ну, в соответствии с «[Системные вызовы (wiki.osdev.org)] (http://wiki.osdev.org/System_Calls)», 'syscall' является эквивалентом AMD Intel' sysenter'. В нем говорится: «* На процессоре Intel, начиная с Pentium II, появилась новая пара инструкций sysenter/sysexit. Он позволяет быстрее переключиться из режима пользователя в режим ядра, ограничив накладные расходы на изменение режима. ** Аналогичная пара команд была создана AMD: Syscall/Sysret **. Однако поведение этих инструкций отличается от поведения Intel. * « – Hibou57

ответ

5

После некоторого поиска в Интернете я приземлился на эту тему на StackOverflow: Linux invoke a system call via sysenter tutorial. В нем говорится, что рекомендуемый способ вызова системы не использует int 80h или syscall или sysenter, но linux-gate.so.

По-прежнему остается вопрос о крушении и ядро-дампе. Мое предположение, наконец, состоит в том, что хотя либо syscall, либо sysenter инструкции доступны в качестве инструкции CPU, может быть, ядро ​​Linux просто не настроено правильно эту «точку входа», когда оно решит, что это не очень полезно на данной аппаратной платформе.

Кажется на 32 бит платформы, sysenter или syscallмогут быть доступны, в то время как он всегда доступен, только на 64-битных платформ.

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

- обновление -

По крайней мере, я мог бы найти это, подтверждающие выше. Это все еще не авторитетная рекомендация, но я считаю верным доверчивым.

What is linux-gate.so.1?, говорит:

Предпочтительный способ вызова системного вызова является определяется ядром во время загрузки и , очевидно, это поле используется SYSENTER.

Кроме того, из другого источника, источник сборки образец FASM (необходим некоторые переводы, если вы используете NASM), чтобы вызвать системную функцию с помощью linux-gate.so: Finding linux-gate.so.1 in Assembly.

+1

Обратите внимание, что при использовании sysenter/syscall соглашение может быть не таким же, как для использования int 0x80. Для 'sysenter' вам нужно, iirc,' push ecx push edx push ebpmov ebp, esp' прямо перед 'sysenter' – nos

+1

Обратите внимание, что поскольку он« определяется ядром во время загрузки », вы получаете int 80 , sysenter или syscall в зависимости от возможностей CPU. Int 80 всегда работает, но работает медленно, а на новых процессорах работает только один из sysenter или syscall. Это не выбор, который должна сделать программа, ядро ​​делает оптимальный выбор для вас. –

5

Intel manual говорит, что syscall недействителен в режиме совместимости (32-разрядный), поэтому он не должен использоваться ядром.

Это, кажется, в Intel-только ограничение однако: https://stackoverflow.com/a/29784932/895245, что AMD не имеет, но, конечно, Linux должен поддерживать Intel :-)

sysenter, кажется, лучший способ сделать это сегодня, как это быстрее, чем int 0x80, но он должен использоваться косвенно через VDSO, как описано в How to invoke a system call via sysenter in inline assembly (x86/amd64 linux)?

+1

Кто-то поднял то же, что и комментарий к первоначальному вопросу. Я ответил, что инструкция скомпилирована ассемблером, который я использовал без предупреждения, а код операции был документирован для 32 бит. Может быть, это неверно в 32-битном режиме с архитектурой 64 бита ... В любом случае, как вы сказали, в контексте Linux лучше полагаться на VDSO (есть способы получить его даже без Glibc). – Hibou57

+1

@ Hibou57: Согласно [этой теме комментариев] (http://stackoverflow.com/questions/38063529/x86-32-x86-64-polyglot-machine-code-fragment-that-detects-64bit-mode-at- run-ti/38063530? noredirect = 1 # comment63566180_38063530): он действителен только в 32-битном режиме только для процессоров AMD. Я тоже был удивлен, что он собирает и разбирает в 32-битном коде, но, судя по всему, AMD внедрила syscall отдельно от архитектуры AMD64 (и, возможно, раньше). Инструкция Intel выиграла для 32-битного режима (как обычно), но AMD стала стандартом для AMD64. –

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