Самый простой стартовый код, который устанавливает стек, выглядит примерно так:
_start:
/* Clear the link register, so debuggers know to terminate their
* backtrace. */
cfi_undefined (ra)
/* Setup the global pointer, which the ABI assumes points to the
* __global_pointer$ symbol. */
.option push
.option norelax
la gp, __global_pointer$
.option pop
/* Setup the stack pointer. This symbol will only be looked at
* here, so you can pick any name you want. */
la sp, __stack_pointer$
/* Call main, leaving the arguments undefined. */
call main
/* Spin after main() returns. */
1:
j 1b
Вы также можете сделать что-то вроде вызова __libc_init_array
и регистрации __libc_fini_array
с помощью atexit
, очистки argc
и argv
(a0 и a1 на главную), перемещения раздела данных и обнуления BSS. в зависимости от того, сколько именно C ABI вы хотите поддерживать.
SiFive's Freedom E SDK содержит полный код запуска: https://raw.githubusercontent.com/sifive/freedom-e-sdk/master/bsp/env/start.S, а также соответствующие скрипты компоновщика для некоторых наших платформ. Вы также можете увидеть более сложные в newlib (https://github.com/riscv/riscv-newlib/blob/riscv-newlib-2.5.0/libgloss/riscv/crt0.S) и glibc (https://github.com/riscv/riscv-glibc/blob/riscv-glibc-2.26/sysdeps/riscv/start.S),), хотя оба они предполагают, что стек уже был инициализирован средой выполнения.