Igo*_*lyk 2 linux assembly android arm stack-pointer
我正在编写一个非常优化的叶子函数,为了使其运行更快,我想使用R13作为通用寄存器。在使用R13并将其从功能返回之前,我通过将R13移至VFP寄存器之一来保留它,方法是将其移回。看起来像这样:
/* Start of the function */
push { r4 - r12, r14 }
vmov s0, r13
/* Body of the function. Here I use R13
* as a general purpose register */
vmov r13, s0
pop { r4 - r12, r14 }
bx lr
Run Code Online (Sandbox Code Playgroud)
而且有效。但是我已经读到某些操作系统假定R13始终用作堆栈指针,并将其用作通用寄存器可能会导致崩溃。我还应该说这个功能只能在Android(Linux)上运行。谢谢!
显然,只有在已经使用了所有其他GP寄存器(包括)的情况下lr,才应考虑这一点,并且即使只关心低32位,也不能将某些工作转移到NEON寄存器中,例如,使用压缩整数。
(仅将SIMD规则用于更大的标量整数通常仅在以下情况下才有用:存在一组隔离的值,这些值与算法中的其他值不相互作用,并且您无需在它们上分支或将它们用作指针。 int和SIMD在某些ARM CPU上运行缓慢。)
如果安装了任何信号处理程序,则当这些信号之一到达时,堆栈指针必须有效。(那是异步的。)
在Linux中,除了信号处理程序外,用户空间堆栈指针没有其他异步用法。 (除非您正在使用GDB进行调试,并使用print foo(123)foo是目标进程中的函数。)
如关于“我可以将rsp用作通用寄存器(此问题的x86-64等效)”的注释中所述,即使对于信号,也存在一种解决方法:
使用sigaltstack建立一个替代堆栈,并指定SA_ONSTACK在标志用于sigaction安装处理程序时。
正如@Timothy所指出的,如果您的SP暂存值可能是恰好“指向”备用堆栈的整数,则信号分配机制将假定这是一个嵌套信号,并且不会修改SP(因为在实际的嵌套中-信号的情况下,将覆盖第一个仍在使用的信号处理程序堆栈)。因此push,除非您分配所需数量的两倍,并且只将上半部分传递给sigaltstack,否则您可能会离开SP进入未映射的页面。(对于简单的信号处理程序,可能只需要2k或4k,这些信号处理程序在执行不多之后就会返回)。
即使使用嵌套信号,这也应该是安全的:只有最外面的信号处理程序才能在alt堆栈的底部附近开始,并使用超出实际altstack的某些分配空间。如果SP仍位于altstack中,则另一个信号将使用该空间以下的空间。否则,如果SP已到达altstack之外,它将使用altstack的顶部。
或者,如果您的GP寄存器中的任何一个需要作为指针,则可以使用SP来保存指向绝对不是alt堆栈的指针,从而避免这种过度分配的需要。 如果它是有效的指针,则在调试程序将当前SP用于某些内容,或者您错改了altstack机制的情况下,您很容易遭受破坏,而不会出错。但这只是失败模式的不同:两者都是灾难性的。
硬件中断将状态保存在内核堆栈上,而不是用户空间堆栈上。如果他们使用了用户堆栈:
(一个进程的所有用户空间线程共享同一页表,并且可以读取/写入彼此的堆栈映射。)
Linux / Android与轻量级RTOS完全不同,后者没有虚拟内存或严格执行特权分离。
| 归档时间: |
|
| 查看次数: |
305 次 |
| 最近记录: |