在 ARM 内联汇编中修改 sp

Modifying sp in ARM inline assembly

我知道有 rules 管理 x86 中堆栈指针的修改:

All memory beyond the current address of RSP is considered volatile: The OS, or a debugger, may overwrite this memory during a user debug session, or an interrupt handler. Thus, RSP must always be set before attempting to read or write values to a stack frame.

我的问题是,ARM 的规则是什么?我正在查看 this 代码(请参阅下面的摘录),它看起来违反了 x86 规则(修改内存 然后 更改堆栈指针),但这是一个ARM 上的问题?

mov r4, sp
sub r4, r4, #128

...

mov r3, #116
1: ldr r7, [r2]
add r2, r2, #4
str r7, [r4]
dd r4, r4, #4
sub r3, r3, #4
cmp r3, #0
ne 1b

sub sp, sp, #128

我试过谷歌搜索,但找到描述在内联 asm 中修改 ARM 堆栈的规范......具有挑战性。有一些关于 ARM 编译器和修改堆栈的文档,但是 gcc 的规则似乎不同。

ARM 没有这样的规则。 CPU(至少Cortex-A/R CPUs)不会在中断情况下自动堆栈寄存器,即使对于Cortex-M,也保证保持顺序。

您所说的 "rule" 有点详细和具体。但是 "rule" 适用于几乎所有使用一个堆栈处理所有事情的处理器。

作为一般规则,您应该首先将您的堆栈指针移动到 "allocate" 您想要的堆栈 space,这样您就可以防止下一个东西将其丢弃。然后将其移回取消分配。

对于 ARM,可能是您链接的代码。您在 arm 中存储了寄存器,这是体系结构参考手册的第一章之一(在分析或编写汇编语言之前需要阅读该章节,尤其是寄存器上的一张图片)。图片描述的异常模式都有自己的堆栈指针。因此,当例如发生中断时,其他一些堆栈指针用于保存状态,因此您的数据不会被破坏。

用户和系统共享一个堆栈指针,但这样内核等代码就可以访问而不会陷入用户模式。系统不用于异常,因此您的代码不会停止并切换状态并破坏堆栈。

现在 ARM 就像任何其他品牌的福特一样。他们制造大卡车、小卡车、SUV、小型汽车、老爷车等。ARM 拥有广泛的处理器内核。 cortex-m 适用于微控制器和其他小型 spaces。它有一个堆栈,当发生异常时,它会为您在堆栈上保存状态,从而破坏您的数据。所以你指出的代码是错误的,你为什么要在 cortex-m 上使用 printf?

编译器可以配置为使用或不使用第二个堆栈指针,x86 世界已经习惯了这个想法(sp 和 bsp),但这不是必需的。为了使(数据)堆栈有用,需要有一个堆栈指针和用于引用堆栈使用部分的指令,堆栈指针相对寻址。在某些平台上,您可以访问堆栈指针并使用另一个寄存器(制作副本)来访问堆栈帧,让堆栈指针自由漫游。不管有没有在内联汇编中触摸堆栈指针通常都是一个非常糟糕的主意,你需要很好地了解你的工具链和这样的代码需要不断维护,编译器的每个新版本或你编译该代码的每个新系统上,您必须亲自检查生成的输出以确保您的操作是安全的。如果你要达到那个水平,为什么要使用内联 asm 并消耗所有这些工时(工作保障?)你会使用 asm 并在第一次就做出安全可靠的东西。如果您只想为该函数提供更多数据,只需创建一个局部变量,它会更改 sp 上的减法,完成。无需内联汇编。如果您希望查看堆栈末尾,请使用汇编而不是内联汇编。如果你想修改堆栈指针或出于某种原因快速分配而不使用局部变量,那么再次使用汇编并在你必须避免损坏你正在玩的数据的系统上移动堆栈指针。

除了使系统崩溃之外,在内联汇编中弄乱堆栈指针没有多大意义。与arm或x86无关或填空。

他们在那里所做的是使用内联汇编在汇编中编写整个函数。这可能只是他们构建系统选择的一个例子,你可以将程序集提供给 gnu C 编译器(如果使用内联汇编,你必须编写特定于编译器的代码,这样你就已经知道你正在使用什么编译器)并生成一个对象就像您可以使用 C。他们可以通过其他方式做到这一点,但并不那么丑陋。不幸的是,这种解决方案并不少见。如果 运行 在 not-cortex-m 上,该代码是安全的,你不能在它的中间添加一个函数调用,因为你会破坏你的数据,他们确实将堆栈指针移动到打电话而不是像正常解决方案那样预先。必须找到作者才能问 "why did they do that" 问题。