VM_POP
is a GBVM instruction used to remove a specified number of values from the top of the VM stack.
Purpose:
The GBVM is a stack-based virtual machine, meaning it uses a stack to store temporary values, function arguments, and return addresses. Instructions like VM_PUSH_CONST
, VM_PUSH_VALUE
, or VM_PUSH_REFERENCE
add values to the stack. VM_POP
is essential for:
VM_POP
can discard it.VM_POP
can be used to remove them, preparing the stack for subsequent operations.Proper stack management is crucial for the stability and correct execution of GBVM scripts. Failing to pop values can lead to stack overflow errors or incorrect data being used in later operations.
Syntax:
VM_POP N
N
: The number of values to be removed from the top of the stack. If N
is 1, only the topmost value is removed. If N
is greater than 1, multiple values are removed in a LIFO (Last-In, First-Out) manner.Usage Example: Cleaning Up After a Calculation
Consider a scenario where you perform a calculation within an RPN block, but the result is only needed temporarily for a conditional check, and then you want to discard it without storing it in a variable.
; In your script:
; Assume VAR_PLAYER_LEVEL and VAR_ENEMY_LEVEL are 8-bit integer variables
VAR_PLAYER_LEVEL:
.R_INT8 5
VAR_ENEMY_LEVEL:
.R_INT8 7
; Calculate the difference in levels (Enemy Level - Player Level)
VM_RPN
.R_REF_MEM .R_INT8, VAR_ENEMY_LEVEL ; Push Enemy Level (7)
.R_REF_MEM .R_INT8, VAR_PLAYER_LEVEL ; Push Player Level (5)
.R_OPERATOR - ; Calculate difference (7 - 5 = 2)
.R_INT8 ; Specify result as 8-bit integer
VM_STOP
; At this point, the value '2' is on top of the stack.
; Let's say we only need to check if the difference is positive, then discard it.
; Check if the difference is greater than 0
VM_IF_CONST .GT, 0, 0, ENEMY_STRONGER, 1
; The '0' for IDXA and IDXB are placeholders here, as VM_IF_CONST can operate on the stack top.
; The '1' for N means pop 1 value (the calculated difference) from the stack after the check.
; If the difference is not greater than 0 (i.e., player is stronger or equal)
VM_LOAD_TEXT TEXT_PLAYER_STRONGER
VM_DISPLAY_TEXT
VM_JUMP END_LEVEL_CHECK
ENEMY_STRONGER:
VM_LOAD_TEXT TEXT_ENEMY_STRONGER
VM_DISPLAY_TEXT
END_LEVEL_CHECK:
; ... continue script ...
TEXT_PLAYER_STRONGER:
.TEXT "You are strong enough!"
.TEXT_END
TEXT_ENEMY_STRONGER:
.TEXT "The enemy is too strong!"
.TEXT_END
In this example, after the VM_RPN
block, the calculated difference (2
) is left on the stack. The VM_IF_CONST
instruction uses this value for its comparison. The N
parameter of VM_IF_CONST
is set to 1
, which effectively performs a VM_POP 1
after the condition is evaluated, removing the temporary difference value from the stack.
Alternatively, if you just wanted to discard the value without a conditional check:
; ... RPN calculation leaving a value on stack ...
VM_POP 1 ; Remove the top value from the stack
Analogy to other programming languages:
This is analogous to explicitly discarding a return value or a temporary variable in languages where you have fine-grained control over memory or stack. In assembly language, POP
instructions are common. In higher-level languages, this kind of explicit stack management is usually handled automatically by the compiler or runtime, but the underlying principle of removing no-longer-needed data from temporary storage remains the same.