Processor model 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
Processor model 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
The above two slides were presented during a lecture wrt x86/MIPS. I haven't understood much.
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.
Is it talking about models for two different processors (x86/MIPS)? Which one is for whom?
Can anyone kindly explain?
Both are x86-like, where call
pushes a return address (PC) onto the stack. Note that PC during execution of the call
instruction points to the end of the instruction / start of the next, so PC is the address of the instruction that should execute after ret
from a call
.
The 2nd model is just more explicit about how the stack works, matching x86 push
/pop
/call
/ret
. That's all it changed.
MIPS jal
puts a return address into a register (the link register $lr
is one of the 32 general-purpose integer regs on MIPS). Software can push it on the stack manually (e.g. in non-leaf functions), but the ISA doesn't know/care about that.
MIPS doesn't even architecturally have a "stack pointer" that's used implicitly for anything. A callstack is a software convention, although a very useful one that essentially all software does use in basically the same way as x86, just without single instructions that combine modifying SP and load or store.
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.
No, this is completely wrong on all levels.
First of all, none of the examples show anything about heap memory, only reserving space for local variables (automatic storage) in the stack. Storage that will be released when a function returns.
"Heap" memory is separate. It's not usually a single thing, e.g. static and dynamic allocation are usually separate in modern OSes. But anyway, dynamic heap allocation like malloc
will give you a pointer to memory that is still valid after add sp, 16
or whatever and ret
to tear down the current function's stack frame.
And 2nd, PC is not involved at all in allocation of storage. The details only show PC being read as a return address, and written by jump/call/ret instructions. It's also known as IP, the instruction pointer. On x86, the 32 and 64-bit versions of the IP register are EIP / RIP respectively.