我正在尝试为Rust中的STM32编写一个bootloader,我无法弄清楚如何正确填充堆栈指针。我可以告诉代码应该是:
asm!("MOV SP, $0" :: "0"(stack_pointer)); // set the stack pointer
但是编译器不同意:
error: invalid operand in inline asm: 'MOV SP, $0'
--> src/main.rs:38:5
|
38 | asm!("MOV SP, $0" :: "0"(stack_pointer)); // set the stack pointer
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: <inline asm>:1:11: error: unexpected token in operand
MOV SP,
^
--> src/main.rs:38:5
|
38 | asm!("MOV SP, $0" :: "0"(stack_pointer)); // set the stack pointer
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
我做错了什么?它似乎在抱怨美元符号,但我是直接从the documentation得到的。
根据评论中的对话,我尝试了两件事,两者都编译(!),但两者似乎都没有用(但这可能是十亿个理由中的任何一个,仍然在努力): / p>
版本A:
asm!("MOV R0, #0x0800");
asm!("LSL R0, R0, #16");
asm!("MOV R1, #0x8000");
asm!("ORR R2, R1, R0");
asm!("LDRT R0, [R2]");
asm!("MOV SP, R0");
entry_point()
版本B:
#[inline(never)]
unsafe fn go(_addr: u32, entry_point: fn()->()) {
asm!("MOV SP, R0");
entry_point()
}
答案 0 :(得分:0)
我最终选择了@ stefan实现@clifford的方法以及以下代码来调用它:
let firmware_address = 0x08008000u32;
unsafe {
let scb = &*stm32f40x::SCB::ptr();
scb.vtor.write(firmware_address);
asm::isb();
go(&*(firmware_address as *const VectorTable));
}