From Esolang
Jump to navigation Jump to search

Mov is an x86 assembly instruction identified to be Turing-complete by Stephen Dolan in mov is Turing-complete [1] and developed further by xoreaxeaxeax in Movfuscator [2]. It may also be considered the basis of a one instruction set computer archtecture which (unlike Subleq) does not have to use self modifying code.

About the Mov instruction

The mov instruction has a number of different forms. Let r1,r2 denote registers, then for example:

  • mov r1, 42  % store the number 42 in r1
  • mov r1, r2  % fetch the value in r2 and store it in r1
  • mov [r1], 42  % store the number 42 in the address the register r1 points to
  • mov r1, [r2]  % fetch the value the address in register r2 points to and store it in r1
  • mov [r1], r2  % store the value register r2 in the address the register r1 points to

The expressions in brackets can also include +offsets or even adding two register together. All of these features are made use of in different encodings.

Equality Test

To test equality of 'x' and 'y':

  mov [x], 0
  mov [y], 1
  mov result, [x]

This works by having a large array which is written into and read back out from. If x = y the readback will give 1 and it would be 0 otherwise.

Arithmetic and Logic

Arithmetic and logic gates can be encoded using lookup tables. For example to find the xor of x and y we have the following lookup tables

  xor_xy: dd xor_0y, xor_1y
  xor_0y: dd 0, 1
  xor_1y: dd 1, 0

and the code is

  mov r1,[xor_xy+x]
  mov r2,[y]
  mov result,[r1+r2]

As a compilation target

The movfuscator repo contains an example compiler from brainfuck to mov instructions. The author also wrote an lcc (C compiler) backend for it. The result is extremely long linear code with no branches which can cause reverse engineering tools to crash.