VM instructions / opcodes

From Final Fantasy XII Wiki
Jump to navigation Jump to search

Final Fantasy XII VM supports 100 known opcodes. There are three types of instructions. Instructions with an immediate, which are 3 bytes long, instructions without immediate, which are 1 byte long and special instructions like NOP and LABEL that have a defined size of zero and thus can't be used, because it causes the VM to loop indefinitely. These are probably used only by compiler and never put in the code itself.

Name Opcode Size Immediate Arguments Description
NOP 0x00 0 no 0 Don't use. It causes eternal loop
LABEL 0x01 0 no 0 Don't use. It causes eternal loop
TAG 0x02 0 no 0 Don't use. It causes eternal loop
SYSHALT 0x03 1 no 0
SYSTEM 0x04 1 no 1
OPLOR 0x05 1 no 2 Logical or
OPLAND 0x06 1 no 2 Logical and
OPOR 0x07 1 no 2 Binary or
OPEOR 0x08 1 no 2 Binary exclusive or
OPAND 0x09 1 no 2 Binary and
OPEQ 0x0a 1 no 2 Compares whether two values on stack are equal
OPNE 0x0b 1 no 2 Compares whether two values on stack are not equal
OPGT 0x0c 1 no 2 Compares whether second value on stack is greater than first
OPLS 0x0d 1 no 2 Compares whether second value on stack is less than first
OPGTE 0x0e 1 no 2 Compares whether second value on stack is greater or equal to first
OPLSE 0x0f 1 no 2 Compares whether second value on stack is less or equal to first
OPSLL 0x10 1 no 2 Shift left logical
OPSRL 0x11 1 no 2 Shift right logical
OPADD 0x12 1 no 2 Addition
OPSUB 0x13 1 no 2 Substraction
OPMUL 0x14 1 no 2 Multiplication
OPDIV 0x15 1 no 2 Division
OPMOD 0x16 1 no 2 Modulo
OPNOT 0x17 1 no 1 Logical negation
OPBNOT 0x18 1 no 1 Binary negation
OPUMINUS 0x19 1 no 1 Not used
OPFIXADRS 0x1a 1 no 1 Not used
PUSHA 0x1b 1 no 0 Pushes contents of A register to stack
POPA 0x1c 1 no 0 Pops stack into A register
PUSHX 0x1d 1 no 0 Pushes contents of X register to stack
PUSHY 0x1e 1 no 0 Pushes contents of Y register to stack
POPX 0x1f 1 no 0 Pops stack into X register
POPY 0x20 1 no 0 Pops stack into Y register
REQ 0x21 1 no 3 Queue script for execution
FREQ 0x22 1 no 3 Not used
TREQ 0x23 1 no 3 Not used
REQSW 0x24 1 no 3 Queue script for asynchronous execution and wait for it to finish.
FREQSW 0x25 1 no 3 Not used
TREQSW 0x26 1 no 3 Not used
REQEW 0x27 1 no 3 Queue script for synchronous execution and wait for it to finish.
FREQEW 0x28 1 no 3 Not used
TREQEW 0x29 1 no 3 Not used
PREQ 0x2a 1 no 3 Not used
PREQSW 0x2b 1 no 3 Not used
PREQEW 0x2c 1 no 3 Not used
RET 0x2d 1 no 0 End function and return
RETN 0x2e 1 no 0
RETT 0x2f 1 no 0
RETTN 0x30 1 no 0
DRET 0x31 1 no 0
REQWAIT 0x32 1 no 2 Wait for a specified queued script to finish
PREQWAIT 0x33 1 no 2 Not used
REQCHG 0x34 1 no 2
REQCANCEL 0x35 1 no 2 Not used (see freqcancel)
POPI0 0x36 1 no 0 Pops stack into I0 register
POPI1 0x37 1 no 0 Pops stack into I1 register
POPI2 0x38 1 no 0 Pops stack into I2 register
POPI3 0x39 1 no 0 Pops stack into I3 register
POPF0 0x3a 1 no 0 Pops stack into F0 register
POPF1 0x3b 1 no 0 Pops stack into F1 register
POPF2 0x3c 1 no 0 Pops stack into F2 register
POPF3 0x3d 1 no 0 Pops stack into F3 register
PUSHI0 0x3e 1 no 0 Pushes I0 register onto stack
PUSHI1 0x3f 1 no 0 Pushes I1 register onto stack
PUSHI2 0x40 1 no 0 Pushes I2 register onto stack
PUSHI3 0x41 1 no 0 Pushes I3 register onto stack
PUSHF0 0x42 1 no 0 Pushes F0 register onto stack
PUSHF1 0x43 1 no 0 Pushes F1 register onto stack
PUSHF2 0x44 1 no 0 Pushes F2 register onto stack
PUSHF3 0x45 1 no 0 Pushes F3 register onto stack
DVAR 0x46 1 no 2 Pops a variable from debug stack and puts on position specified as argument
LONGCODESTART 0x47 1 no 0 Not used
PUSHV 0x48 3 yes 0+dimensions Push variable value onto stack
POPV 0x49 3 yes 0+dimensions Pops stack into variable
PUSHDBG 0x4a 3 yes 0+dimensions Pushes variable onto debug stack
PUSHP 0x4b 3 yes 0+dimensions Pushes pointer to a variable onto stack
PUSHTAG 0x4c 2 yes 0+dimensions Not used (pushes script number)
PUSHACT 0x4d 3 yes 0+dimensions Not used (pushes function number)
PUSHI 0x4e 3 yes 0 Pushes integer from integer table onto stack
PUSHII 0x4f 3 yes 0 Pushes signed 16bit integer immediate onto stack
PUSHF 0x50 3 yes 0 Pushes float from float table onto stack
JMP 0x51 3 yes 0 Unconditionally jumps to an offset specified by an index in script's jump table
POPCMPYEQJMP 0x52 3 yes 1 Pops stack and jumps if equal to Y register
POPCMPYLOWJMP 0x53 3 yes 1 Pops stack and jumps if less than Y register
POPCMPYLOWEQJMP 0x54 3 yes 1 Pops stack and jumps if less or equal to Y register
POPCMPYHIGHJMP 0x55 3 yes 1 Pops stack and jumps if greater than Y register
POPCMPYHIGHEQJMP 0x56 3 yes 1 Pops stack and jumps if greater or equal to Y register
POP2CMPYBTWNJMP 0x57 3 yes 2 Pops two values from stack and jumps if Y register's value is between (including) these values
CALL 0x58 3 yes 0+args Calls external function (by specifying its number in VM's call table). Function's return value is left on stack.
CALLACT 0x59 3 yes 1+args Calls external function (by specifying its number in VM's call table) in context of another script (pops its number from stack). Function's return value is left on stack.
POPXJMP 0x5a 3 yes 1 Pops stack into X register and jumps unconditionally
POPXCJMP 0x5b 3 yes 1 Pops stack into X register and jumps if true[1]
POPXNCJMP 0x5c 3 yes 1 Pops stack into X register and jumps if false[1]
CALLPOPA 0x5d 3 yes 0+args Calls external function (by specifying its number in VM's call table). Function's return value is popped into A register.
CALLACTPOPA 0x5e 3 yes 1+args Calls external function (by specifying its number in VM's call table) in context of another script (pops its number from stack). Function's return value is popped into A register.
REQALL 0x5f 3 yes 0 Queues all scripts within REQ table specified by an immediate for execution.
JMPINTERNAL 0x60 3 yes 0 Not used (normal jumps cover entire script)
REQWAITALL 0x61 3 yes 0 Waits for all scripts within REQ table specified by an immediate to finish.
INCINITTAG 0x62 3 yes 0
REQIALL 0x63 3 yes 0 Waits for all scripts within REQ table specified by an immediate to finish.

References

  1. 1.0 1.1 values on stack evaluate to true if they're greater than zero and to false otherwise