我在这个论坛上阅读了很多主题,并在这个主题上找到了很多答案.我实现了从汇编代码中将5个参数传递给C函数.为此,我使用了以下说明:
mov r0, #0
mov r1, #1
mov r2, #2
mov r3, #3
mov r4, #4
STR r4, [sp, #-4]!
BL displayRegistersValue
Run Code Online (Sandbox Code Playgroud)
但是今天我试图将整个寄存器传递给C函数以将它们保存在C结构中.我尝试了这个指令:
STMDB sp!, {registers that i want to save}
Run Code Online (Sandbox Code Playgroud)
我的C功能:
displayRegistersValue(int registers[number_of_registers])
char printable = registers[0] + (int)'0'; // Convert in a printable character
print_uart0(&printable);
Run Code Online (Sandbox Code Playgroud)
但我的表现并不好.那么,我如何访问C代码中的寄存器?
非常确定ARM标准只允许R0-R3通过值传递4个最大值.如果你需要更多的值,那么将它们推入堆栈并以这种方式访问它们 - 就像编译器那样.或者创建一个结构并传递其地址.
好吧,加倍cheked,我就在这里是ARM调用约定的链接 - 在页面下面一点.
要执行您想要的操作,请将某个内存位置(数组)的地址传递到汇编例程中.一旦你有了这个地址,可能在r0之内,你可以stmdb!进入该位置所有寄存器值和该存储器将在C级别可见.
要注意,这可能不会按照你的想法去做.根据上面的调用约定链接,允许这些值发生相当大的变化.如果这是用于调试,最好使用调试器并以这种方式观察寄存器.
好的,你仍然不理解这里:
{
int registerValues[14];
myAsmRoutine(registerValues);
print_uart0(& registerValues);
}
myAsmRoutine:
stmia r0!, {r1-r14}
blx lr
Run Code Online (Sandbox Code Playgroud)
我跳过了R0和PC,但你明白了.此外,你需要做一些复杂的事情来将值更改为可打印的格式 - sprintf或itoa os之类的东西.