使用GCC和STM32时堆栈帧不正确
我试图在GNUGCC(而不是ARMGCC)中创建简单的SVC处理程序。如果调用了SVC服务,它将正确地输入使用GCC和STM32时堆栈帧不正确,gcc,assembly,arm,stm32,svc,Gcc,Assembly,Arm,Stm32,Svc,我试图在GNUGCC(而不是ARMGCC)中创建简单的SVC处理程序。如果调用了SVC服务,它将正确地输入SVC\u Handler(),但当我尝试查找用于调用SVC Handler的SVC编号(SVC\u number)时,我得到的是值248,而不是1 我用的是CubeMX IDE和Nucleo-F401RE板 代码: void SVC\u处理程序(void) { 挥发性物质( “TST lr,#4\t\n” “ITE EQ\t\n” MRSEQ r0,msp\t\n MRSNE r0,psp
SVC\u Handler()
,但当我尝试查找用于调用SVC Handler的SVC编号(SVC\u number
)时,我得到的是值248,而不是1
我用的是CubeMX IDE和Nucleo-F401RE板
代码:
void SVC\u处理程序(void)
{
挥发性物质(
“TST lr,#4\t\n”
“ITE EQ\t\n”
MRSEQ r0,msp\t\n
MRSNE r0,psp\t\n
“B%[SVC\U处理程序\U主]\t\n”
:
:[SVC_Handler_Main]“i”(SVC_Handler_Main)
:“r0”
);
}
void SVC_Handler_Main(无符号int*SVC_参数){
uint8_t svc_编号;
svc_编号=((字符*)svc_参数[6])[-2];
开关(svc_编号){//
这将创建形式为svc#1
的汇编程序。请注意,“1”在指令运算码中编码。为了找到“1”,您必须查看lr
并在该地址加载运算码,然后解析(通过屏蔽)该值
比如说,
ldr r1,[lr] ; load svc opcode to r1 (might need an offset)
and r1, r1, #SVC_MASK ; may need shifts as well.
这是无效的,因为您将代码管道视为数据。通常的方法是定义服务寄存器,如r7
,然后将r7
设置为svc\0
指令之前的“#1”。因此,宏类似于
#define svc(code) asm volatile ("mov r7, %[immediate]\n" \
" SVC #0"::[immediate] "I" (code) \
: "r7" /*clobbers r7*)
您可以只使用r0
,但如果您的调用层次结构变得更复杂,许多函数可能会将参数放入r0、r1、r2、r3中,然后您需要将它们洗牌。这就是通常使用r7
的原因
为什么svc_数
等于248,而我期望的是1
看起来你认为它是放在堆栈上的,但事实并非如此。值248只是堆栈上的随机值。不建议提供负整数作为数组的参数。事实上,你将无符号int转换为char上的指针…我想问题就在那一行上。转储the svc_args array.define你所说的服务编号是什么意思?你是如何传递服务编号的?@Heyji使用带负int的cast-on-char*作为索引是许多书籍/在线资源用于svc的方法。直接传入指令或寄存器还是什么?这是个问题,为了提取服务编号,如果你不知道n这是您的第一个问题,然后,一旦您知道您可以找出为什么看不到它,看起来您希望SVC\u Handler
成为\uu attribute\uu((裸))
,因为您在内联asm中使用b
指令来离开函数。如果您让GCC发出函数序言,这可能会改变情况(特别是在调试构建中)。如果它将优化的构建内联到调用程序中,那就更糟了。(虽然如果它只是通过硬件调度调用,这并不是一个问题。)尽管我见过很多使用我提供的语法(其中之一在Cortex M4的最终指南中)对GNU GCC进行SV调用的示例,使用r7作为svc代码的保持器的解决方案对我很有效。谢谢!我明白了,我认为偏移量“6”对于您的系统可能会有所不同,这取决于异常表中发生的情况;除非svc\u Handler
是主要条目。基本上,偏移量“6”是试图获取lr
和指令b的外观ack 2个字节,应该是SVC
编号(我猜低字节是假定endianess的掩码操作,对于Cortex-M很好)。
ldr r1,[lr] ; load svc opcode to r1 (might need an offset)
and r1, r1, #SVC_MASK ; may need shifts as well.
#define svc(code) asm volatile ("mov r7, %[immediate]\n" \
" SVC #0"::[immediate] "I" (code) \
: "r7" /*clobbers r7*)