最近在调试riscv,没有使用工具链下的printf函数,自己改造了printf函数,但是调试中发现,pintf中需要被格式化输出的字符一直无法找到,但是字符串能正常输出。最简demo如下:
int printf_s(const char *fmt, ...)
{
va_list vaArgP;
//
// Start the varargs processing.
//
va_start(vaArgP, fmt);
va_end(vaArgP);
return 0;
}
我现在明白的是可变参数解析需要使用va_start找到函数参数在栈内的地址。一般来说,fmt和vaArgP的栈内地址是连续的,且vaArgP表示可变参数的地址。这种用法在arm下是正常运作的。但是在riscv下发现,这样的printf函数无法正确输出。同样方法下,vaArgP已经不再能正确表示可变参数部分的数据了。
反汇编看到如下汇编代码:
自己定义的printf_s函数内的参数压栈动作,a0和a1被压进了不同的栈地址。a0和a1正好表示的是printf_s函数的参数。
因为这两个地址不是连续地址,所以使用va_start得到的栈指针已经不能正确得到形参的地址了。
这种可变参数函数参数解析用法在arm下看着正常,但在riscv下目前看不能正确使用。