# The OS/K Team licenses this file to you under the MIT license. # See the LICENSE file in the project root for more information. #---------------------------------------------------------------------------# # Special instructions # #---------------------------------------------------------------------------# # # Initiate machine shutdown (STOP) # # THROW #SHT # # Throws: # #SYS if not in supervisor mode # #ILL if disabled through DV # #SHT otherwise # stop #---------------------------------------------------------------------------# # Logical instructions # #---------------------------------------------------------------------------# # # Bitwise NOT operation # # $1 = NOT($1) # # Preserves all flags # not rm # # Bitwise OR operation # # $1 = $1 OR $2 # # Clears OF and CF # Sets ZF and SF according to the result # or rm rim orf rm rim # # Bitwise AND operation # # $1 = $1 AND $2 # # Clears OF and CF # Sets ZF and SF according to the result # and rm rim andf rm rim # # Bitwise XOR operation # # $1 = $1 XOR $2 # # Clears OF and CF # Sets ZF and SF according to the result # xor rm rim xorf rm rim # To document shl rm rim shr rm rim shlf rm rim shrf rm rim #---------------------------------------------------------------------------# # Arithmetic instructions # #---------------------------------------------------------------------------# # # Arithmetical SGN operation # # IF ($1 == 0) THEN # $2 = 0 # ELIF ($1 GT 0) THEN # $2 = 1 # ELSE # $2 = LONG_MIN # FI # # Treats $1 and $2 as signed values # Sets ZF and SF according to the result # sgn rm rim sgnf rm rim # # Arithmetical NEG operation # # $1 = NOT($1) + 1 # # Sets CF if $1 == 0; clears it otherwise # Sets OF if $1 == $LONG_MIN; clears it otherwise # Sets ZF and SF according to the result # neg rm negf rm # # Arithmetical INC operation # # $1 = $1 + 1 # # Preserves CF # Sets OF if $1 == $LONG_MAX, clears it otherwise # Sets ZF and SF according to the result # inc rm incf rm # # Arithmetical DEC operation # # $1 = $1 - 1 # # Preserves CF # Sets OF if $1 == $LONG_MIN, clears it otherwise # Sets ZF and SF according to the result # dec rm decf rm # # Arithmetical ADD operation # # $1 = $1 + $2 # # Sets CF if unsigned integer overflow occur, clears it otherwise # Sets OF is signed integer overflow occur, clears it otherwise # Sets ZF and SF according to the result # add rm rim addf rm rim # # Arithmetical ADD operation, with carry # # $1 = $1 + $2 + CF # # Sets CF if unsigned integer overflow occur, clears it otherwise # Sets OF is signed integer overflow occur, clears it otherwise # Sets ZF and SF according to the result # adc rm rim adcf rm rim # # Arithmetical SUB operation # # $1 = $1 - $2 # # Sets CF if unsigned integer overflow occur, clears it otherwise # Sets OF is signed integer overflow occur, clears it otherwise # Sets ZF and SF according to the result # sub rm rim subf rm rim # # Arithmetical unsigned MUL operation # # $1 = LO($1 * $2) # # Sets CF and OF if HI($1 * $2) > 0, clears them otherwise # Preserves ZF and SF # mul rm rim mulf rm rim # # Arithmetical unsigned DIV operation # # $1 = $1 DIV $2 # # Preserves all flags # div rm rim # # Arithmetical unsigned MOD operation # # $1 = $1 MOD $2 # # Preserves all flags # mod rm rim # # Arithmetical unsigned 128-bit MUL operation # # RDX = HI(RAX * $1) # RAX = LO(RAX * $1) # # Sets CF and OF if HI($1 * $2) > 0, clears them otherwise # Preserves ZF and SF # mul2 rim mul2f rim # # Arithmetical unsigned combined DIV and MOD operations # # RDX = (RAX MOD $1) # RAX = (RAX DIV $1) # # Preserves all flags # div2 rim #---------------------------------------------------------------------------# # Comparison instructions # #---------------------------------------------------------------------------# # # TEST Comparison instruction # # $1 AND $2 # # Clears OF and CF # Sets ZF and SF according to the result # test rim rim # # CMP Comparison instruction # # $1 - $2 # # Sets CF if unsigned integer overflow occur, clears it otherwise # Sets OF is signed integer overflow occur, clears it otherwise # Sets ZF and SF according to the result # cmp rim rim #---------------------------------------------------------------------------# # Jump instructions # #---------------------------------------------------------------------------# # # Unconditional jump (JMP) instruction # # RIP = $1 # j ri jmp ri # # RCX-dependent jump (LOOP) instruction # # IF (RCX > 0) THEN # RCX = RCX - 1 # RIP = $1 # FI # loop ri #---------------------------------------------------------------------------# # Movement instructions # #---------------------------------------------------------------------------# # # Load Effective Address (LEA) instruction # # $1 = ADDR($2) # # For instance: # LEA RAX, [RBX + RCX + 4] # will result in: # RAX = RBX + RCX + 4 # # Preserves all flags # lea rm m # # Movement (MOV) instruction # # $1 = $2 # mov rm rim # # Movement with zero-extension (MOVZX) instruction # # $1 = ZeroExtend($2) # movzx rm m # # Exchange (XCHG) instruction # # $_ = $1 # $1 = $2 # $2 = $_ # xchg rm rim # # Compare-and-exchange (CMPXCHG) instruction # # IF ($1 == RAX) THEN # $1 = $2 # ZF = 1 # ELSE # RAX = $1 # ZF = 0 # FI # # Preserves CF, OF and SF # cmpxchg rm rim #---------------------------------------------------------------------------# # Stack manipulation instructions # #---------------------------------------------------------------------------# # # Unconditional jump with possible return (CALL) # # PUSH(RIP) # JMP(RIP) # call rim # # Return to caller (RET) # # POP(RIP) # ret # # Make new stack frame (ENTER) # # PUSH(RBP) # RBP = RSP # RSP = RSP - $1 # enter i # # Leave stack frame (LEAVE) # # RSP = RBP # POP(RBP) # leave #---------------------------------------------------------------------------# # String manipulation instructions # #---------------------------------------------------------------------------# # # Store value into string (STOSx) # # [%str] = $val # IF (DF == 0) THEN # %str = %str + sizeof(x) # ELSE # %str = %str - sizeof(x) # FI # # When no parameters are given, %str = RDI and $val = RAX # When one parameter is given, %str = RDI and $val = $1 # When two parameters are given, %str = $1 and $val = $2 # stosb stosb rim stosb r rim # # Load value from string (LODSx) # # %dest = [%str] # IF (DF == 0) THEN # %str = %str + sizeof(x) # ELSE # %str = %str - sizeof(x) # FI # # Preserves CF, OF and SF # Sets ZF according to the loaded value # # When no parameters are given, %dest = RAX and %str = RSI # When one parameter is given, %dest = $1 and %str = RSI # When two parameters are given, %dest = $1 and %str = $2 # lodsb lodsb r lodsb r r lodsw lodsw r lodsw r r lodsl lodsl r lodsl r r lodsq lodsq r lodsq r r # # Scan string for a particular value (SCASx) # # CMP([%str], $val) # # IF (DF == 0) THEN # %str = %str + sizeof(x) # ELSE # %str = %str - sizeof(x) # FI # # Sets CF, OF, ZF and SF according to the result of the comparison # # When no parameters are given, %str = RDI and $val = RAX # When one parameter is given, %str = RDI and $val = $1 # When two parameters are given, %str = $1 and $val = $2 # # Note that SCASx moves in the string no matter whether the value # was found or not; therefore when the value *is* found, it will # be sizeof(x) bytes below the current value of %str # scasb scasb rim scasb r rim scasw scasw rim scasw r rim scasl scasl rim scasl r rim scasq scasq rim scasq r rim # # Scan string for null terminator (SCAZSx) # # CMP([%str], 0) # # IF (ZF == 0) # IF (DF == 0) THEN # %str = %str + sizeof(x) # ELSE # %str = %str - sizeof(x) # FI # FI # # Sets CF, OF, ZF and SF according to the result of the comparison # # When no parameters are given, %str = RDI and $val = RAX # When one parameter is given, %str = RDI and $val = $1 # When two parameters are given, %str = $1 and $val = $2 # # Unlike SCASx, this instruction does NOT move forward after # finding what it was looking for. The instruction: # REP.NZ SCAZSx %str # serves as a much faster shorthand for # REP.NZ SCASx %str # DEC %str # scazsb scazsb r scazsw scazsw r scazsl scazsl r scazsq scazsq r # # Compare bytes in strings (CMPSx) # # CMP([%str1], [%str2]) # # IF (DF == 0) THEN # %str1 = %str1 + sizeof(x) # %str2 = %str2 + sizeof(x) # ELSE # %str1 = %str1 - sizeof(x) # %str2 = %str2 - sizeof(x) # FI # # Sets CF, OF, ZF and SF according to the result of the comparison # # When no parameters are given, %str1 = RDI and %str2 = RSI # When one parameter is given, %str1 = RDI and %str2 = $1 # When two parameters are given, %str1 = $1 and %str2 = $2 # cmpsb cmpsb r cmpsb r r cmpsw cmpsw r cmpsw r r cmpsl cmpsl r cmpsl r r cmpsq cmpsq r cmpsq r r # # Safe compare bytes in strings (CMPZSx) # # Behaves precisely like CMPSx, except in the following case: # - If both [%str1] and [%str2] are zero, clears ZF (indicating NOT EQUAL) # # This prevents 'REP.Z CMPZSx' from looping infinitely when both strings # have the exact same content; this allows for short strcmp's # cmpzsb cmpzsb r cmpzsb r r cmpzsw cmpzsw r cmpzsw r r cmpzsl cmpzsl r cmpzsl r r cmpzsq cmpzsq r cmpzsq r r # # Move value from string to string (MOVSx) # # [%str1] = [%str2] # IF (DF == 0) THEN # %str1 = %str1 + sizeof(x) # %str2 = %str2 + sizeof(x) # ELSE # %str1 = %str1 - sizeof(x) # %str2 = %str2 - sizeof(x) # FI # # Preserves CF, OF and SF # Sets ZF according to the moved value # # When no parameters are given, %str1 = RDI and %str2 = RSI # When one parameter is given, %str1 = RDI and %str2 = $1 # When two parameters are given, %str1 = $1 and %str2 = $2 # movsb movsb r movsb r r movsw movsw r movsw r r movsl movsl r movsl r r movsq movsq r movsq r r #---------------------------------------------------------------------------# # Supervisor only instructions # #---------------------------------------------------------------------------# # # Call an architecture-reserved function slot of device (DEVCTL) # # See dv/DEVAPI # devctl rim rim # # Call a device-defined function slot of device (IOCALL) # # See dv/DEVAPI # iocall rim rim #---------------------------------------------------------------------------# # Flag manipulation instructions # #---------------------------------------------------------------------------# # # Clear or set interrupt flag (CLI/STI) # # Throws: # #SYS if not in supervisor mode # cli sti # # Clear or set direction flag (CLD/STD) # cld std # # Complement, clear or set carry flag (CMC/CLC/STC) # cmc clc stc # # Load FLG register (LODF) # # $1 = FLG # lodf rm # # Store FLG register - lower byte only (STOFB) # # FLG[7:0] = $1[7:0] # # Note: FLG's lower byte contains CF, OF, ZF, SF, PF and DF # stofb rm #---------------------------------------------------------------------------# # Byte-wise / bit-wise manipulation instructions # #---------------------------------------------------------------------------# # # Byte/word/dword swap (xSWAP) # # Change endianness # bswap rm rim wswap rm rim dswap rm rim #---------------------------------------------------------------------------# # Misc. instructions # #---------------------------------------------------------------------------# # # Do nothing (NOOP) # # (nothing) # # Throws: # (nothing) # # Preserves all flags # nop # # CPU Identification Number # # Does nothing (for now) # cpuid # # Pseudo-random number generation (RAND32/RAND64) # # RAND32 generates a 32-bit pseudo-random number using # a nonlinear additive feedback pseudo-random number generator # of period 16 * (2^31 - 1). # # RAND64 generates two such numbers, and store them in the destination # operand's higher and lower double words respectively # # The running program does not control the seeding and the processor # may generate numbers from the same generator for other purposes # than this instruction # #rand32 rm #rand64 rm # # Get code/data offset (GCO/GCD) # # $1 = CR1 (GCO) # $1 = CR2 (GCD) # gco rm gcd rm # # Send a character to standard output (PRN) # # Throws: # #PRN if DV text mode enabled # #PRN if graphic mode enabled # prn rim #---------------------------------------------------------------------------# # Debugging instructions # #---------------------------------------------------------------------------# # # Breakpoint instruction (BREAK) # # (cause register dump on standard error) # (wait for user input before proceeeding) # break # # Step-by-step execution (STEP) # # IF $1 == 0 THEN # (disable step-by-step execution) # ELSE # (enable step-by-step execution) # FI # step rim #---------------------------------------------------------------------------# # Clean-up misc. instructions # #---------------------------------------------------------------------------# # # Clear base volatile registers (CLR) # # RAX = RBX = RCX = RDX = 0 # RSX = RBI = RDI = RSI = 0 # clr # # Clear argument registers (CLA) # # AX0 = AX1 = AX2 = AX3 = 0 # AX4 = AX5 = AX6 = AX7 = 0 # cla #---------------------------------------------------------------------------# # Deprecated instruction # #---------------------------------------------------------------------------# # # PUSH value onto stack # # RSP = RSP - 8 # *RSP = $1 # # Throws: # #STA if RBP MOD 8 > 0 # #STA if RSP MOD 8 > 0 # #STU if RSP > RBP # !push rim # # POP value from stack # # $1 = *RSP # RSP = RSP + 8 # # Throws: # #STA if RBP MOD 8 > 0 # #STA if RSP MOD 8 > 0 # #STU if RSP >= RBP # !pop rm #---------------------------------------------------------------------------#