简体   繁体   English

ARM程序集。 使用负偏移量存储和加载堆栈中的数据

[英]ARM assembly. Storing and loading data from stack with negative offset

Can we store and load data from the stack with negative address offset like in the following code snippet? 我们可以使用负地址偏移量来存储和加载堆栈中的数据,如下面的代码片段所示吗? Is it safe to write and read data from the memory address that is actually outside ( [sp, #-16] or [sp, #-20] ) of the stack boundaries? 从堆栈边界外部( [sp, #-16][sp, #-20] )的内存地址写入和读取数据是否安全? Thanks! 谢谢!

stmdb sp, { r4 - r6 }

mov r4, #255
str r4, [sp, #-16]

mov r3, #127
str r3, [sp, #-20]

ldr r4, [sp, #-20]

sub sp, #12
ldmia sp, { r4 - r6 }

This is a question of ABI, rather than architecture or language, so ultimately it depends on the operating environment and ABI in force. 这是ABI的问题,而不是架构或语言,所以最终它取决于运行环境和有效的ABI。

Whilst you can access addresses below SP, in the sense that a load or store with a base register of r13 and a negative offset is a perfectly valid instruction, it's only the ABI which dictates whether your data will be safe there or not, and whether such an access is guaranteed not to segfault in the first place. 虽然您可以访问SP以下的地址,但是基本寄存器r13和负偏移的加载或存储是完全有效的指令,只有ABI指示您的数据是否安全,以及是否这样的访问保证不会首先出现段错误。 Most systems in current use will probably be using some variant of the ARM EABI, whose procedure call standard says, as part of "Universal stack constraints": 当前使用的大多数系统可能正在使用ARM EABI的一些变体,其程序调用标准称,作为“通用堆栈约束”的一部分:

A process may only access (for reading or writing) the closed interval of the entire stack delimited by [SP, stack-base – 1] (where SP is the value of register r13). 进程只能访问(用于读取或写入)由[SP,stack-base-1]分隔的整个堆栈的闭合间隔(其中SP是寄存器r13的值)。

ie Whilst nothing will actually prevent you violating that constraint, try it and all bets are off. 即虽然没有什么能够真正阻止你违反这一限制,但试试吧,所有的赌注都会被取消。

Since you mention Android, which is definitely EABI (specifically the GNU variant), the most obvious concern there is the way the Linux kernel delivers signals. 既然你提到了Android,它肯定是EABI(特别是GNU变体),那么最明显的问题就是Linux内核提供信号的方式。 If your process happens to take a signal immediately after str r3, [sp, #-20] , a signal handler may run using the process stack, so when (if) normal execution resumes, whilst SP itself will be back to the same value it was before, who knows what ldr r4, [sp, #-20] will actually load. 如果您的进程恰好在str r3, [sp, #-20]之后立即发出信号,则信号处理程序可以使用进程堆栈运行,因此当(if)正常执行恢复时,SP本身将返回相同的值之前,谁知道ldr r4, [sp, #-20]实际上会加载什么。

Note that some environments might give certain additional guarantees about what goes on below the stack pointer, and if you're in a bare-metal scenario or otherwise in complete control then you can do whatever you like, but generally, unless you know otherwise then assume the answer to be "no". 请注意, 某些环境可能会对堆栈指针下方的内容提供某些额外的保证,如果您处于裸机场景或完全控制,那么您可以做任何您喜欢的事情,但通常情况下,除非您不知道然后假设答案是“不”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM