Сохраняются ли системные вызовы в регистрах?

Помните, что расширение параметров не происходит волшебным образом, вам нужна оболочка, которая сделает это за вас.

var=3 /bin/echo `$var`

Я не уверен, что вы пытаетесь сделать с этим, назад -тики здесь не подходят (они выполняют команду и заменяются ее выводом ).

var=3 bash -c "/bin/echo '$var'"

не работает, потому что расширение параметра происходит до назначения, поэтому текущая оболочка заменяет "/bin/echo '$var'"на /bin/echo ''(, предполагая, что varне определено ), а дочерняя оболочка запускается с

/bin/echo ''

Попробуйте

var=3 bash -c 'echo $var'

вместо :здесь одинарные кавычки защищают аргумент от текущей оболочки, а новая оболочка запускается с

echo $var

, который будет обработан так, как вы ожидаете.

Что касается вашего второго пункта, мой первоначальный комментарий остается в силе. Если вы хотите поиграть со средой и посмотреть, что произойдет, запустите envи вместо этого отфильтруйте вывод:

var=3 env | grep var
var=3 exec env | grep var
0
07.08.2018, 19:34
1 ответ

Нет "системного вызова... для каждого регистра".

Интерфейс системного вызова зависит от аппаратной архитектуры. Часто (почти всегда? )случай, когда процесс сохраняет целое число, соответствующее требуемому системному вызову, в предварительно -определенном регистре, а затем выполняет инструкцию, которая запускает ЦП для передачи исполнения коду обработки системных вызовов ядра. Ядро обращается к предварительно определенному -регистру, чтобы определить, какой системный вызов запрашивает процесс, а затем выполняет соответствующий обработчик системного вызова.

Например, рассмотрим эту программу «hello world» в сборке x86 _64 для Linux:

$ cat hello.s
       .text
       .global
main:
        movq $1,   %rax # write() system call number
        movq $1,   %rdi # first parameter  -- standard output file descriptor
        movq $msg, %rsi # second parameter -- buffer
        movq $14,  %rdx # third parameter  -- buffer length
        syscall         # invoke system call

        movq $60,  %rax # exit() system call number
        movq $0,   %rdi # first parameter  -- exit status
        syscall         # invoke system call; this will never return

       .section.rodata
msg:
       .ascii "Hello, world!\n"

$ gcc hello.s
$./a.out
Hello, world!
$

Для x86 _64 номер системного вызова хранится в регистре rax, первый параметр системного вызова хранится в rdi, второй параметр системного вызова хранится в rsi, а третий параметр хранится в rdx.

Пример начинается с помещения значения 1в регистр rax. 1— номер системного вызова для системного вызова write(). Далее 1помещается в регистр rdi; 1— дескриптор файла для стандартного вывода, а rdi— регистр для первого параметра. Затем адрес msgсохраняется в регистре rsi; rsi— второй параметр. Затем 14сохраняется в rdx; 14 — длина строки, а rdx— регистр для третьего параметра. Затем инструкция syscallзапускает ЦП для передачи управления коду ядра. Ядро проверяет rax,использует значение в этом регистре (1 ), чтобы определить, какой системный вызов следует выполнить (write ), а затем вызывает соответствующий обработчик.

Когда ядро ​​завершает выполнение системного вызова, управление возвращает процесс пользовательского пространства. Он записывает 60для регистрации rax; снова rax— регистр для номера системного вызова, а здесь 60— номер системного вызова для exit(). Записывает 0в регистр rdi— первый (и единственный )параметр системного вызова exit; статус выхода. Опять же, инструкция syscallзаставляет ЦП передать управление коду ядра. Ядро проверяет rax, использует значение в этом регистре (60 ), чтобы определить, какой системный вызов следует выполнить (exit ), затем вызывает соответствующий обработчик. Обработчик exit()завершает процесс, так что инструкция никогда не возвращается.

Примеры, выполняющие одну и ту же задачу, будут различаться в зависимости от аппаратной архитектуры; это даже не то же самое для 32 -бит Intel.

4
28.01.2020, 02:18

Теги

Похожие вопросы