我试图创造简单的SVC处理在GNU GCC (不是武装GCC)。如果调用SVC服务,它将正确地进入SVC_Handler(),但是当我试图找到用于调用SVC (svc_number)的SVC编号时,我得到的值为248而不是1。
我使用的是CubeMX IDE和Nucleo-F401RE板。
代码:
void SVC_Handler(void)
{
asm volatile (
"TST lr, #4\t\n"
"ITE EQ\t\n"
"MRSEQ r0, msp\t\n"
"MRSNE r0, psp\t\n"
"B %[SVC_Handler_Main]\t\n"
:
: [SVC_Handler_Main] "i" (SVC_Handler_Main)
: "r0"
);
}
void SVC_Handler_Main(unsigned int* svc_args) {
uint8_t svc_number;
svc_number = ((char* )svc_args[6])[-2];
switch(svc_number) { // <- that's where I get 248 instead of 1
case SVC_ADD:
SVC_Add_Handler(svc_args[0], svc_args[1]);
break;
default:
break;
}
}
int __attribute__ ((noinline)) SVC_Service_Add(int x, int y) {
svc(SVC_ADD);
}
#define SVC_ADD 1
#define svc(code) asm volatile ("SVC %[immediate]"::[immediate] "I" (code))我在svc_number之后使用了带断点的观察者表达式,它的值是248,而不是应该是的1。
服务调用(SVC)主要用于实时操作系统的设计,使软件进入特权模式。ARM GCC对SV呼叫有一些很好的支持,而在GNU GCC中,你必须自己做。理论是这样的:当一个SV调用(在我的例子中是SVC_Service_Add() )被调用时,它会调用SVC_Handler()。SVC_Handler()检查使用哪个堆栈(main或process ),该信息是通过读取链接寄存器(LR)的第2位找到的。根据这一点,msp或psp都保存在r0中。然后,编译器将r0、r1、r2、r3、r12、r14、返回地址和xPSR放在svc_args中,这样就可以在SVC_Handler_Main中使用这些参数。svc_args=r0,svc_args1=r1,...svc_args6=SP(我们感兴趣的,保存SVC编号的那个)。因为Cortex M4堆栈是完全降序的,所以我们需要做-2来获得我们感兴趣的svc_args6的字节。由于对SVC_Handler的调用是由SVC_ADD宏(0x01)完成的,所以((char *) svc_args6)-2应该等于SVC_ADD,因此可以从SVC_Handler_Main()调用适当的函数。我没有得到1,因为某种原因我得到了248。
问题:为什么svc_number等于248,而我期望1
发布于 2020-02-04 03:50:42
#define svc(code) asm volatile ("SVC %[immediate]"::[immediate] "I" (code))这将创建表单svc #1的汇编程序。请注意,“1”是在指令操作代码中编码的。为了找到'1',您必须查看lr并在该地址加载op代码,然后解析(通过掩蔽)值。
例如,
ldr r1,[lr] ; load svc opcode to r1 (might need an offset)
and r1, r1, #SVC_MASK ; may need shifts as well.当您将代码管道视为数据时,这是不有效的。通常的方法是定义一个服务寄存器,比如r7,然后在svc #0指令之前将r7设置为'#1‘。所以,宏就像,
#define svc(code) asm volatile ("mov r7, %[immediate]\n" \
" SVC #0"::[immediate] "I" (code) \
: "r7" /*clobbers r7*)您可以只使用r0,但是如果调用层次结构变得更加复杂,许多函数可能会将arg放入r0、r1、r2、r3中,然后需要对它们进行洗牌。这就是为什么通常使用r7。
为什么
svc_number等于248,而我期望的是1
看起来,您认为它是放在堆栈上的,这是,而不是。248值只是堆栈上的随机值。
https://stackoverflow.com/questions/60045830
复制相似问题