Assembly 1: single cmd printf("hello...\n"); asm("lw ra,12(sp)"); asm("ret"); printf("...world!\n"); --- Assembly 2: with output void *sp; asm("mv %0, sp" : "=r"(sp)); --- Assembly 3: with input void *sp = (void*)0x803fffc0; asm("mv sp,%0" :: "r"(sp)); --- register handler asm("csrw mtvec, %0" ::"r"(handler)); --- helper functions #define CLINT0_MTIME 0x200bff8 #define CLINT0_MTIMECMP 0x2004000 unsigned long long helper_mtime_get() { int low = *(int*)(CLINT0_MTIME); int high = *(int*)(CLINT0_MTIME + 4); return (((long long)high) << 32) | low; } void helper_mtimecmp_set(unsigned long long time) { *(int*)(CLINT0_MTIMECMP + 0) = (int)time; *(int*)(CLINT0_MTIMECMP + 4) = (int)(time >> 32); } --- set timer helper_mtimecmp_set(helper_mtime_get() + QUANTUM); --- enable timer interrupt int mstatus, mie; asm("csrr %0, mstatus" : "=r"(mstatus)); asm("csrw mstatus, %0" ::"r"(mstatus | 0x8)); asm("csrr %0, mie" : "=r"(mie)); asm("csrw mie, %0" ::"r"(mie | 0x80)); --- See which interrupts int mcause; asm("csrr %0,mcause" : "=r"(mcause)); printf("cause: %d\n", mcause); ---