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

Is the difference between programming model wrt Program Counter and Stack Pointer in case of Assembly?

处理器型号 I

 ● 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   

处理器型号 II

● More realistic version of model I  
● Stack explicitly implemented in memory  
● Stack Pointer register - SP  
● Stack operations defined explicitly using SP  
● Allocation and deallocation of local data implemented 
   by changing the value of SP (no data transfer occurs)
● Arguments and local variables accessed by names  
    Still unrealistic  

  Instruction    Action               Description
  ---------------------------------------------------------------------
  load data      A = data             Load data to accumulator (constant or variable)
  store data     data = A             Store data from accumulator to memory
  add data       A += data            Add data to accumulator (constant of variable)
  push data      *--SP = data         Place data on the stack (constant of variable)
  call addr      *--SP = data         Jump storing the return trace on the stack
                 PC = addr            
  return         PC = *SP++           Return to the previously stored trace address
  Create data    SP -= sizeof(data)   Allocate data on the stack
  Destroy data   SP += sizeof(data)   Deallocate data from the stack

以上两张幻灯片是在 x86/MIPS 的一次讲座中展示的。我不太明白。

我唯一理解的是,调用函数有两种模型,使用堆栈和 allocating/freeing 堆。一个用PC,一个用SP。

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

谁能解释一下?

两者都是类似 x86 的,其中 call 将 return 地址 (PC) 压入堆栈。请注意,call 指令执行期间的 PC 指向指令的结尾/下一条指令的开始,因此 PC 是 ret 之后应从 call 执行的指令的地址.

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

MIPS jal 将 return 地址放入寄存器(link 寄存器 $lr 是 MIPS 上 32 个通用整数寄存器之一)。软件可以手动将其压入堆栈(例如,在非叶函数中),但 ISA 不会 know/care 这样做。

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

Only thing I understood is, there are two models of calling functions using stacks, and allocating/freeing heaps. One uses PC and another uses SP.

不,这在所有层面上都是完全错误的。

首先,none 的示例显示了有关堆内存的任何内容,只为堆栈中的局部变量(自动存储)保留了 space。函数 returns.

时将释放的存储

“堆”内存是独立的。它通常不是一个单一的东西,例如。静态和动态分配在现代操作系统中通常是分开的。但无论如何,像 malloc 这样的动态堆分配会给你一个指向内存的指针,该内存在 add sp, 16 或其他什么之后仍然有效,并且 ret 会拆除当前函数的堆栈框架。

第二,PC 根本不参与存储分配。详细信息仅显示 PC 被读取为 return 地址,并由 jump/call/ret 指令写入。它也被称为 IP,指令指针。在x86上,32位和64位版本的IP寄存器分别是EIP/RIP。