ARM64:从程序集分支到函数时如何保护整个堆栈

ARM64:从程序集分支到函数时如何保护整个堆栈,arm,arm64,Arm,Arm64,我有以下ARM64汇编代码: .text .arch armv8-a .type testARM64, STT_FUNC .global testARM64 testARM64: arg1 .req x0 arg2 .req x1 arg3 .req x2 arg4 .req x3 arg5 .req x4 arg6 .req x5 tmp .req x9 mov tmp, #0 mov x0, #1 bl debugAssem

我有以下ARM64汇编代码:

.text
.arch armv8-a
.type testARM64, STT_FUNC
.global testARM64

testARM64:
arg1    .req x0
arg2    .req x1
arg3    .req x2
arg4    .req x3
arg5    .req x4
arg6    .req x5
tmp .req x9


    mov tmp, #0

    mov x0, #1
    bl debugAssembly

    mov tmp, #2

    ret

.unreq arg1
.unreq arg2
.unreq arg3
.unreq arg4
.unreq arg5
.unreq arg6
.unreq tmp
我称之为:

#include <stdlib.h>

void testARM64(int arg1, int arg2, int arg3, int arg4, int arg5, int arg6);

void debugAssembly(int a) {
    fprintf(stderr, "Debug 0x%d\n", a);
}

int main(int argc, char **argv) {
    testARM64(0, 0, 0, 0, 0, 0);
    return 0;
}
#包括
无效测试RM64(int arg1、int arg2、int arg3、int arg4、int arg5、int arg6);
无效调试程序集(int a){
fprintf(stderr,“调试0x%d\n”,a);
}
int main(int argc,字符**argv){
testARM64(0,0,0,0,0,0);
返回0;
}

当分支到debugAssembly时,如何保护整个堆栈?我的意思是,无论参数的数量如何,无论我在程序集中对任何临时寄存器执行什么操作,推/弹出ARM指令的等效功能是什么?(我不需要保护/保存车道)。

您需要保存fp reg和链路寄存器——通常使用stp x29、x30、[sp,#0x10]之类的工具完成!假设您的平台对fp使用x29——在您调用另一个函数并在退出该函数之前恢复值之前。否则,当您禁用其他函数时,链接寄存器(保存调用方的返回地址)将被覆盖。您的ABI可能需要堆栈指针的16字节对齐,因此即使您的平台不使用帧指针,您也需要将两个寄存器保存到堆栈中


我建议您分解编译器生成的一些简单函数,并将其指令用作您自己手工编写的例程的模型。

您需要保存fp reg和link寄存器——通常使用stp x29、x30、[sp,#0x10]之类的工具来完成!假设您的平台对fp使用x29——在您调用另一个函数并在退出该函数之前恢复值之前。否则,当您禁用其他函数时,链接寄存器(保存调用方的返回地址)将被覆盖。您的ABI可能需要堆栈指针的16字节对齐,因此即使您的平台不使用帧指针,您也需要将两个寄存器保存到堆栈中


我建议您分解编译器生成的一些简单函数,并将其指令用作自己手工编写例程的模型。

ARM过程调用标准应该有助于ARM过程调用标准应该有助于我使用gcc-S来理解gcc是如何实现的,但它始终是针对当前情况的。我换了多少个寄存器。我希望能够在任何需要的地方复制粘贴相同的调试代码,而不必担心堆栈/寄存器的状态。所以我的问题是“整堆”,我不明白你说的“整堆”是什么意思。您可以将所有非易失性(或“被调用方已保存”)寄存器保存在函数序言(函数的开头)中,然后在函数尾声(函数的结尾)中恢复它们——这对所有手写函数都是安全的。假设您的ABI符合AAPCS,那么InfinitelyManic链接的AAPCS是需要保存内容的良好参考。请注意,保存比需要保存的寄存器更多的寄存器是低效的…&编写手写程序集的唯一原因是为了实现关键的效率函数。我使用gcc-S来理解gcc是如何实现的,但它总是针对当前的情况,即aka。我换了多少个寄存器。我希望能够在任何需要的地方复制粘贴相同的调试代码,而不必担心堆栈/寄存器的状态。所以我的问题是“整堆”,我不明白你说的“整堆”是什么意思。您可以将所有非易失性(或“被调用方已保存”)寄存器保存在函数序言(函数的开头)中,然后在函数尾声(函数的结尾)中恢复它们——这对所有手写函数都是安全的。假设您的ABI符合AAPCS,那么InfinitelyManic链接的AAPCS是需要保存内容的良好参考。请注意,保存比需要保存的寄存器更多的寄存器是低效的…&编写手写程序集的唯一原因是为了实现关键的效率功能。。