Mov Is Turing Complete [Paper Implementation]
A Step-by-Step Coding Guide to Understanding One-Instruction Set Computers using the MOV opcode
LeetArxiv Intro
LeetArxiv is Leetcode for implementing Arxiv and other research papers in your preferred programming language.
We help programmers whose jobs are threatened by AI to transition into careers in research by providing simple, step-by-step coding guides.
1. Introduction
The paper, mov is Turing-complete, showcases how computer programmers only require the mov instruction to write software.
This paper demonstrates a possible approach to building One Instruction Set Computer (OISC)1 architectures. No opcodes, no compile-time optimizations, just one instruction : mov.
For web-devs, the paper suggests an idea similar to how people write entire codebases using TypeScript’s type-system because it is turing complete.2
We suggest opening the paper link in a separate tab while reading the walkthrough.
*We provide a C implementation that can be translated to other languages.
*Dm me on twitter @murage_kibicho if you want me to feature your programming language translation.
1.1. Why is this paper important?
It proves Intel’s chips are over-complicated, hinting at the growing dominance of ARM and RISC chips in modern computers.
It shows how to create malware that’s difficult to reverse-engineer. This is because all you see are mov instructions in Assembly during deobfuscation.
Finally, this paper nurtures the concept of minimalism when generating machine code. This promotes the development of one-instruction set computers.
The paper is 4 pages long. We’ll highlight the important sections in each page then provide code.
2. Turing Machines and the x86 mov Instruction
This section introduces turing machines and the mov instruction in x86 Assembly language.
2.1 Quick Introduction to Turing-machines

A Turing machine is a device, that when given enough time, can run any computer program.3
A programming language is turing-complete if it can take code, run the code and output a result. For instance, JavaScript is a turing-complete language.4
According to the paper, for a language to be turing-complete, we need:
A way to read and write to storage. Writing on a tape, or writing to Random Access Memory. In the paper, this is similar to moving through the transition table on page 2.
The ability to stop and output a result. This is the ‘distinguished blank symbol’ on page 1, section 3.
A form of conditional jumps, like if or while statements. These are the transition states represented by the diagram on page 2.
Examples of languages that are not turing-complete :
The entire class of total functional programming languages like Dhall. These are languages that always terminate, i.e No halting problem 5
Coq, the theorem proving language. It’s turing-incomplete so you don’t accidentally get stuck in an infinite loop while proving math theorems6.
P.S. Being turing-incomplete is not bad in practice. Turing completeness is only useful when working with infinities.7
2.2. Quick Introduction to the x86 mov Instruction

The x86 Assembly mov instruction is designed to move data from one location to another. In our implementation, the locations tend to be computer registers, and by moving data, we mean “copy data between registers”.
*mov permits data transfer between registers and memory.
*mov can perform both loading and storing data
The general x86 mov syntax is :
mov destination, source
In the screenshot at the start of this section, the paper author showcases three alternative ways to call mov. Here are some examples to help you understand.
// Load the immediate value 42 into the eax register
1. Load immediate : mov eax, 42 ;
// Load the value at memory address (ebx + ecx*4) into eax
2. Load indexed : mov eax, [ebx + ecx*4] ;
// Store the value in eax at memory address (ebx + ecx*4)
3. Store indexed : mov [ebx + ecx*4], eax ;
2.2.1. How to perform comparisons with mov

The author asserts that we can perform comparisons using only load and store instructions. We explain the first mov instructions in the screenshot above.
2.2.1.1 Performing Comparisons using Load and Store
mov [Ri], 0
: store a value 0 in address Ri.
mov [Rj], 1
: store a value 1 in address Rj.
mov Rk, [Ri] :
Finally, read the value at Ri and store it in Rk.
The value in
Rk
will now be0
or1
, depending on whetherRi
andRj
point to the same memory location.
This is a clever trick to perform comparisons. It uses the fact “writing to memory destroys any exisiting data”.
Here are some more examples to help understand:
Case 1:
R_i == R_j
(Both registers point to the same memory location):After the first instruction (
mov [Ri], 1
), the memory cell atRi
(which is the same asRj
) contains1
.The second instruction (
mov [Rj], 1
) overwrites the same memory cell with1
.The third instruction (
mov Rk, [Ri]
) reads the value1
from the memory cell and stores it inRk
.Result:
Rk = 1
.
Case 2:
Ri != Rj
(Registers point to different memory locations):After the first instruction (
mov [Ri], 0
), the memory cell atRi
contains0
, but the memory cell atRj
remains unchanged.The second instruction (
mov [Rj], 1
) writes1
to the memory cell atR_j
, but this does not affect the memory cell atR_i
.The third instruction (
mov R_k, [R_i]
) reads the value0
from the memory cell atR_i
and stores it inR_k
.Result:
R_k = 0
.
The second portion of the screenshot introduces [N], a lookup table. It does the same thing as above. The author simply showcases that one can perform table lookups using the mov opcode.
3. Coding Guide : Simulating a Turing Machine using Mov

This sections focuses on implementing a theoretical Turing machine. We’ll follow this YouTube video by Christopher Domas to implement practical computing operations.
3.1. Implementing an if statement
We presented a comparison algorithm in section 2. Here’s a summary.
Inside shared memory, define two values at different memory offsets.
Load 0 and 1 at each of the memory offsets.
Read the value at memory[value1] to get the comparison result.
Let’s compare 10 and 20. (Feel free to change the values defined in value1)
You can copy the code and run the code here
section .data
memory times 256 db 0 ; Define a shared memory region (256 bytes)
value1 dd 10 ; Define value1 = 10 (offset into memory)
value2 dd 20 ; Define value2 = 20 (offset into memory)
result dd 0 ; Define result = 0
output db '0', 0 ; Define output string (initialized to '0')
section .text
global _start
_start:
; Step 1: Store 0 at memory[value1]
mov eax, [value1] ; Load value1 into eax
mov byte [memory + eax], 0 ; Store 0 at memory[value1]
; Step 2: Store 1 at memory[value2]
mov eax, [value2] ; Load value2 into eax
mov byte [memory + eax], 1 ; Store 1 at memory[value2]
; Step 3: Read the value at memory[value1] into result
mov eax, [value1] ; Load value1 into eax
mov bl, [memory + eax] ; Move the value at memory[value1] into bl
mov [result], bl ; Move the value of bl into result
; Step 4: Convert the value in result to ASCII
add byte [result], '0' ; Convert 0 to '0' or 1 to '1'
mov al, [result] ; Load the value of result into al
mov [output], al ; Store the ASCII value in the output string
; Step 5: Print the value in result (just to see outout)
mov eax, 1 ; syscall: write
mov edi, 1 ; file descriptor: stdout
lea rsi, [output] ; address of output string
mov edx, 1 ; number of bytes to write
syscall
; Exit the program
mov eax, 60 ; syscall: exit
xor edi, edi ; status: 0
syscall
This proves we can create a turing-complete language using only mov.
We declared variables using mov.
We performed a branching (if comparison) using mov.
We were able to read the value at a specific memory address using mov.
In the next post, we show how to build a One Instruction Set Computer for the finite field assembly programming language.
One-Instruction Set Computers. Wikipedia. https://en.wikipedia.org/wiki/One-instruction_set_computer
TypeScript Type System is turing-complete. Hacker News. https://news.ycombinator.com/item?id=14905043
What is Turing-complete? StackOverflow. https://stackoverflow.com/a/37247136/13035630
JavaScript is turing-complete. FreeCodeCamp.https://www.freecodecamp.org/news/javascript-is-turing-complete-explained-41a34287d263/
Total Functional Programming Languages. Wikipedia. https://en.wikipedia.org/wiki/Total_functional_programming
Main Advantage of Turing-Incomplete Programming Languages. Computer Science Stack Exchange. https://cs.stackexchange.com/questions/110842/what-are-the-benefits-of-languages-that-are-not-turing-complete
Nothing Wrong with Turing-Incomplete Languages. StackOverflow. https://stackoverflow.com/a/29489459/13035630