在ARM上将参数从asm传递到C

del*_*tMe 2 c assembly arm

我在这个论坛上阅读了很多主题,并在这个主题上找到了很多答案.我实现了从汇编代码中将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代码中的寄存器?

Mic*_*gan 5

非常确定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之类的东西.