在汇编情况下,编程模型wrt程序计数器和堆栈指针之间是否有区别?

时间:2019-03-22 07:23:49

标签: assembly x86 mips program-counter stack-pointer

处理器模型I

queryActivityStarting(from: to:)

处理器模型II

 ● Registers  
    PC – Program Counter  
    Single data register (accumulator) without name  
    We will use symbol A to describe operations on this register  
 ● Stack with an unspecified implementation  
 ● Data specified by name or value  
    More realistic model will follow later 

  Instruction     Action         Description  
  ---------------------------------------------------------------------
  load data       A = data       Load data to accumulator  
  store data      data = A       Store data from accumulator to memory  
  add data        A += data      Add data to accumulator  
  push data                      Push data onto stack  
  call addr       Push PC        Jump and store return trace on the stack 
                  PC = addr
                  Pop PC 
  return          Pop PC         Return – jump to the previously stored trace addr  
  create data                    Allocate data on stack  
  destroy data                   Deallocate data from stack   

以上两张幻灯片是在x86 / MIPS上的一次演讲中介绍的。我不太了解。

据我所知,有两种使用堆栈和分配/释放堆的函数调用模型。一个使用PC,另一个使用SP。

是否在谈论两个不同处理器(x86 / MIPS)的模型?哪个是给谁的?

有人可以解释吗?

1 个答案:

答案 0 :(得分:4)

两者均类似于x86,其中call将返回地址(PC)压入堆栈。请注意,在执行call指令期间,PC指向指令的末尾/下一条指令的开始,因此PC是应从retcall之后执行的指令的地址。

第二个模型更加明确地说明了堆栈的工作方式,匹配x86 push / pop / call / ret。这就是所有的

MIPS jal将返回地址放入寄存器中(链接寄存器$lr是MIPS上的32个通用整数寄存器之一)。软件可以手动将其推送到堆栈中(例如,在非叶子功能中),但是ISA对此并不了解/不在乎。

MIPS在结构上甚至没有隐式用于任何事物的“堆栈指针”。调用堆栈是一种软件约定,尽管这是一种非常有用的约定,它基本上所有软件 都以与x86基本上相同的方式使用,而没有将修改SP和加载或存储结合在一起的单个指令。

  

据我所知,有两种使用堆栈和分配/释放堆的函数调用模型。一个使用PC,另一个使用SP。

否,这在所有级别上都是完全错误的。

首先,所有示例都没有显示任何有关堆内存的内容,仅在堆栈中为局部变量(自动存储)保留了空间。函数返回时将释放的存储空间。

“堆”内存是单独的。通常不是一件简单的事情,例如在现代操作系统中,静态和动态分配通常是分开的。但是无论如何,像malloc这样的动态堆分配将为您提供一个指向在add sp, 16或之后的任何有效且ret之后仍然有效的内存指针,以拆除当前函数的堆栈帧。

第二,PC根本不参与存储分配。详细信息仅显示PC被读取为返回地址,并通过跳转/调用/退出指令写入。它也称为IP(指令指针)。在x86上,IP寄存器的32位和64位版本分别为EIP / RIP。