Function 具有4个以上寄存器的函数调用ARM组件

Function 具有4个以上寄存器的函数调用ARM组件,function,assembly,stack,arm,gnu,Function,Assembly,Stack,Arm,Gnu,我试图将r0-r5传递到函数check。然而,只有寄存器r0-r3通过引用进行复制。在我的主要功能中,我有以下代码 push {lr} mov r0, #1 mov r1, #2 mov r2, #3 mov r3, #4 mov r4, #5 mov r5, #6 bl check pop {lr} bx lr 在我的check函数中,我有这个代码。这是在一个单独的文件中,也不确定这是否重要 m: .as

我试图将r0-r5传递到函数
check
。然而,只有寄存器r0-r3通过引用进行复制。在我的主要功能中,我有以下代码

    push {lr}
    mov r0, #1
    mov r1, #2
    mov r2, #3
    mov r3, #4
    mov r4, #5
    mov r5, #6
    bl check
    pop {lr}
    bx lr
在我的
check
函数中,我有这个代码。这是在一个单独的文件中,也不确定这是否重要

    m: .asciz "%d, %d ~ (%d, %d, %d)
    ...
    push {lr}
    ldr r0, =m
    bl printf
    pop {lr}
    bx lr

这个的输出是
2,3~(4337721994545180)
。我正在尝试学习汇编,所以你能用谷歌来解释答案吗?我知道我需要使用堆栈,但我不知道如何使用它,我想学习如何使用。提前谢谢。

您可以试试看

void check ( unsigned int, unsigned int, unsigned int, unsigned int, unsigned int );

void call_check ( void )
{
    check(1,2,3,4,5);
}
armlinuxgnueabigcc-c-O2 check.c-o check.o armlinux gnueabi objdump-D check.o

00000000 <call_check>:
   0:   e52de004    push    {lr}        ; (str lr, [sp, #-4]!)
   4:   e3a03005    mov r3, #5
   8:   e24dd00c    sub sp, sp, #12
   c:   e58d3000    str r3, [sp]
  10:   e3a00001    mov r0, #1
  14:   e3a01002    mov r1, #2
  18:   e3a02003    mov r2, #3
  1c:   e3a03004    mov r3, #4
  20:   ebfffffe    bl  0 <check>
  24:   e28dd00c    add sp, sp, #12
  28:   e8bd8000    ldmfd   sp!, {pc}
00000000:
0:e52de004推送{lr};(str lr,[sp,#-4]!)
4:e3a03005 mov r3,#5
8:e24dd00c子sp,sp,#12
c:e58d3000 str r3[sp]
10:e3a00001 mov r0,#1
14:e3a01002 mov r1,#2
18:e3a02003 mov r2,#3
1c:e3a03004 mov r3,#4
20:ebfffffe bl 0
24:e28dd00c添加sp,sp,#12
28:e8bd8000 ldmfd sp!,{pc}
当然,这可以手动优化,仍然可以正常工作。也许他们在16字节/4字/64位边界上保持堆栈对齐是对堆栈指针进行额外12字节修改的原因?不知道。但除此之外,您可以看到,您自然需要保存链接寄存器,因为您正在调用另一个函数。r0-r3是显而易见的,然后根据eabi,堆栈上的第一件事是参数的第五个字


同样,对于check函数,您可以简单地让编译器启动。如果查看代码,r0将作为第一个参数出现,然后将其更改为printf的第一个参数,从而将其丢弃。printf需要6个参数才能传入。您需要将它们移到一个位置,第一个要检查的参数是printf的第二个参数,第二个要检查的参数是printf的第三个参数,依此类推。因此,代码必须进行这种转换(其中两个现在在堆栈上)。

如果您不太熟悉所涉及的所有内容,那么阅读该代码可能会有点困难,但您可以找到EABI调用约定的官方定义,以供参考。