mvbg

VM_POP

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:

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

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.