今天有两个堆栈的活动CPU架构吗?

时间:2015-12-27 14:00:39

标签: assembly cpu-architecture

通常使用两个堆栈防止缓冲区溢出探测更简单吗? 一个用于变量和传递参数的堆栈,另一个用于返回地址。

或者像NX / XD位(在AMD / Intel x86上)作为非可执行堆栈这样做会更好吗?

2 个答案:

答案 0 :(得分:4)

Itanium有两个堆栈。我相信一个用于存储局部变量(如数组和东西),而另一个用于存储返回地址。这样,您就无法通过超越缓冲区来覆盖返回地址。

https://blogs.msdn.microsoft.com/oldnewthing/20050421-28/?p=35833

答案 1 :(得分:1)

32位ARM

除了使用r13作为堆栈指针从返回的完整下降堆栈中加载程序计数器(出于分支预测目的将其视为返回值)之外,指令集对于用作堆栈指针的寄存器或堆栈增长的方向是中性的。在汇编语言中,“ push”和“ pop”只是加载和存储指令的备用名称。

Thumb是16位宽的指令集,具有首选的堆栈指针,但其他寄存器也可以同样好用。

要捕获的是多个堆栈,需要多个推入/弹出指令。

AVR

没有指令要增加或减少堆栈指针,也没有指令原子地将堆栈指针设置为新值。因此,创建堆栈框架可能涉及:

  1. 加载堆栈指针的低字节。
  2. 加载堆栈指针的高字节。
  3. 执行16位减法。
  4. 保存中断允许状态。
  5. 禁用中断。
  6. 存储堆栈指针的高字节。
  7. 存储堆栈指针的低字节。
  8. 恢复中断启用状态。

未能禁用中断可能导致浪费200个字节的RAM,这可能导致堆栈溢出。 (某些AVR型号具有1024字节的RAM)

至少有一个C编译器使用一对通用寄存器作为数据栈指针,可以将其原子地添加或减去。