ARM程序集 - 为什么我的应用程序在归零r7时崩溃了?

Mar*_*tin 0 c linux assembly gcc arm

我在尝试运行一个调用非常简单的ARM汇编函数的C程序时遇到了一个奇怪的问题.这是我的C代码:

#include <stdio.h>
#include <stdlib.h>

extern void getNumber(int* pointer);

int main()
{
    int* pointer = malloc(sizeof(int));

    getNumber(pointer);

    printf("%d\n", *pointer);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这是我的汇编代码:

.section .text
.align 4
.arm
.global getNumber
.type getNumber STT_FUNC

getNumber:
    mov  r1, #0
    str  r1, [r0]
    bx   lr
Run Code Online (Sandbox Code Playgroud)

到现在为止还挺好.但是,如果我mov r7, #0在顶部添加一行getNumber,则程序在尝试访问时会出现段错误pointer.在用gdb检查之后,我注意到现在指针本身存储在一个非常低的地址,例如0xa.

现在,我做了一些研究,显然r7是THUMB代码的帧指针(根据这个).但是,我清楚地说明我不想.arm在汇编代码中的行中使用THUMB指令.为什么它失败了?

我正在使用arm-linux-gnueabihf-gcc编译.c和.s文件,我正在运行Arch Linux的基于Cortex-A8的板上运行该程序.

编辑:如果我使用-fomit-frame-pointer标志进行编译,程序运行正常.但是,我仍然想知道为什么使用r7作为帧指针.

编辑2:即使我使用.code 32而不是,它仍然失败.arm.

Mic*_*urr 10

ARM过程调用标准规定了以下内容:

子程序必须保留寄存器r4-r8,r10,r11和SP(以及将r9指定为v6的PCS变体中的r9)的内容.

因此,汇编语言子例程必须保存并恢复r7(如果它使用它).

您可能通过不编译Thumb模式来避免小型测试程序的问题,但您只是意外地避免了问题.链接到汇编例程的任何内容都有权期望保留r7.

  • 这个.这一千倍.使用更高级语言混合程序集而无需彻底了解正在使用的ABI是_asking for trouble_. (4认同)