使用GCC和STM32时堆栈帧不正确

使用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

我试图在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\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*)