Как общее практическое правило, сборка, которую вы пишете на ассемблере, является собственным языком программирования, который, похоже, очень похож на то, что написано в руководстве по RISC-V ISA.RISC-V является довольно простым ISA, поэтому для большинства инструкций фактически нет разницы между синтаксисом руководства ISA и синтаксисом, принятым ассемблером.Место, где это начинает ломаться, - это когда ссылаются на символы, потому что, хотя вы можете заполнить непосредственное непосредственно в вашем ассемблерном коде, вы, вероятно, захотите полагаться на компоновщик, потому что вы не будете знать фактический адрес символа до времени ссылки (и это может измениться при изменении вашей программы).
Для того, чтобы компоновщик мог заполнять адреса символов в вашем коде, вам нужно отправить перемещения из ассемблера, чтобы компоновщик мог позже заполнить их.У меня есть целое сообщение в блоге о том, как это работает в блоге SiFive, но мы просто обновили сайт, и я не могу понять, как его найти:).
В этом случае вы, по сути, пытаетесь написатьассемблер, который реализует следующий код C
int num = 97;
void func(int val) { num = val; }
. В исходном ответе все данные верны, поэтому единственное, о чем нужно беспокоиться, это как вывести правильные инструкции.У вас есть несколько вариантов, как их испускать.Один из вариантов заключается в явном написании каждой инструкции и перемещения в ваш исходный код, который будет выглядеть следующим образом:
func:
lui t0, %hi(num)
sw a0, %lo(num)(a0)
ret
Вы можете сгенерировать эту сборку из моего кода C выше, скомпилировав с -mcmodel=medlow -mexplicit-relocs -O3
.Руководство GCC определяет другие специфичные для RISC-V опции, которые управляют генерацией кода.
Если вас интересует более подробная информация, у нас есть руководство по программированию на GitHub: https://github.com/riscv/riscv-asm-manual/blob/master/riscv-asm.md.Это далеко не завершено, но мы хотели бы получить помощь, чтобы указать на проблемы или предоставить больше контента.