Если ваш измененный код выглядит следующим образом:
void execute_system_call(short value, const int *arguments, int argument_count) {
// TODO: Use arguments
asm volatile (
"li 0, %0\n\t"
"sc\n\t"
:
: "i"(value)
);
}
- тогда вы просите gcc передать переменную value
как немедленную (поскольку вы все еще используете "i"
в качестве ограничения). Поскольку value
является переменной, а не немедленной, это не сработает, что является причиной ошибки, которую вы видите там.
Вместо этого вам нужно будет использовать ограничение ввода "r", чтобы сослаться на значение регистра:
void execute_system_call(short value, const int *arguments, int argument_count) {
// TODO: Use arguments
asm volatile (
"li 0, %0\n\t"
"sc\n\t"
:
: "r"(value)
);
}
- но на этот раз ограничения верны, а сборка - нет. li
принимает регистр и немедленный, но нам нужны два регистра.
Итак, мы, вероятно, хотим mr
(«регистр перемещения»), а не li
:
void execute_system_call(short value, const int *arguments, int argument_count) {
// TODO: Use arguments
asm volatile (
"mr 0, %0\n\t"
"sc\n\t"
:
: "r"(value)
);
}
Это должно выполнить инструкцию sc
с r0
, содержащей value
.
Однако это еще не совсем завершено. Поскольку ваш системный вызов, вероятно, что-то возвращает, вам также необходимо описать это в выходных ограничениях встроенного asm. Способ сохранения возвращаемого значения будет зависеть от ABI системы, с которой вы работаете.
Также, в зависимости от вашего системного вызова ABI, инструкция sc
может изменять другие регистры и / или память. Вы также должны были бы перечислить их в константах clobber оператора asm.
Тогда у нас есть входные аргументы. Реальная реализация этого будет зависеть от вызова функции ABI вашей программы и системного вызова ABI кода супервизора.
Если они довольно похожи, вы можете обнаружить, что гораздо проще реализовать execute_system_call
в качестве фактического ASM, чем C-with-inline-ASM. Таким образом, вам не нужно распаковывать аргументы из C во встроенный ASM. В противном случае вам нужно будет создать похожий код для размещения элементов массива arguments
в определенных регистрах.
И, как проверка работоспособности, разве ваша платформа не обеспечивает функцию syscall
? Это звучит именно то, что вы ищете здесь.