From Esolang
Jump to: navigation, 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 movuscator repo contains an example compiler from brainfuck to mov instructions. The author also wrote a lcc (C compiler) backend for it. The result is extremely long linear code with no branches which can cause reverse engineering tools to crash.