H311 Assembly

From Esolang
Jump to navigation Jump to search

1.0 xH331 Assembly (Inferno)

Malbolge but your computer will quit

xH331 Assembly is an Assembly inspired (not quite only a little) language designed to be the 9th circle of hell after Malbolge. The name Inferno is quite fitting - it will probably burn down your computer :O.

The langauge is based on pain and misery, from Base-60 to deleting system32. The pain is visible from its Hello World program:

tqf7V!uPtht;~nP•WEX9BR0xKjP^uYA7bRM~nZ~EJ0~nYAEXvAU;~nYAv56

This code is AI-GENERATED (yes its that hard). Don't take this with a dime as it's probably not 100% correct, but correct enough to show the nature of this language.

2.0 Control flow

There is only one direction: down. Good luck.

Also, every command is its own line >:).

3.0 Basic Syntax

The Stack

The stack — or correctly: The stacks are a little bit different. They all have 10 slots.

Each of these 10 slots contain 16 bytes of information — with 4 stacks in total. Why that is will become important later.

Variables

Short: No. There are no variables like in other programming languages. Even though you can still create "variables":

name = (stack, Base-60-value)

The problem is that there is no stack index to be used, and it wont push to the top.

This is the first evil of Inferno: Stack interactions are random. That means when pushing to a stack, it overrides a random slot. If the 10th slot is taken, it will override an existing random slot.

These variables can only be used in arithmetic operations - to which we'll get to.

Operations

Arithmetic operations are equal to Malbolge's crazy operation. The exact calculation for the crazy(a, b) operation is:

(a*37+b*19+(a^b)*11)%60

This generates a deterministic value for every calculation that seems random.


Here is how the arithmetic operations look:

sum(a, b) //sum. crazy(a, b)

diff(a, b) //difference. crazy(max(a, b), min(b, a))

prod(a, b) //product. crazy(a^2, (b-5)*11) div(a, b) //division. crazy((a/b)^2, (b/a)^-2 * b^2 * a^3)

Extra commands

push(stack, variable) //1% chance to increase program size by 10 GB (with garbage data)

pop(stack) //pops a random value (good luck). 1% chance to delete program and 0.1% chance to delete a file from system32 (only a non-important file, like the windows kernel)

sum //might corrupt a line

diff //same

prod //same

div //might divide every stack's slots with the next slot (might-might)

print(toPrint) //might print links to... questionable websites

printin(variable) //gets user input. Might hex-encode it by accident (Compiler slipped on a banana sorry :( )

4.0 Encoding Process

The encoding process in xH311 Assembly transforms human-readable source code into a deeply obfuscated form required for successful compilation. This process occurs in three primary stages: EASY-encoder, HARD-encoder, and an optional FINAL_ENCODE transformation.

The initial human-readable code is written using predefined commands (see section 3.0). Each command is one line. The compiler expects only fully encoded input, and each transformation stage builds upon the last.

EASY-Encoder

The EASY-encoder performs a series of transformations to obfuscate readable xH311 code. It operates as follows:

Step 1: Character Mapping

All valid characters (letters A–Z, a–z, digits 0–9, and 38 special characters) are mapped to unique IDs from 1 to 100.

The exact map for it is:

AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz 1234567890;(){}[]@,.:-÷*•+/\!¡?<>_—=&#"'`´%§µ^°$

Step 2: ID Transformation

Each character c is replaced with the character at ID:

(id(c) * 3) % 100

Step 3: Character Insertion

For each original character c, two characters are inserted:

Between: (⌊id(c) / 2⌋ + 1) % 100

After: (id(c) * 2) % 100

Only original characters are processed. Inserted characters are not further modified in this step.

Step 4: Contextual Adjustment

Each character's ID is updated by:

  • Subtracting the ID of the previous character (or 0 if none),
  • Adding the ID of the next character (or 0 if none),
  • Taking the result modulo 100.

This step was originally dynamic (modifying the context for future characters), but in some implementations, dynamic updates are removed for determinism.

Step 5: Line Offset

The number of the original line (i.e., command) is added to each character's ID. Then, the length of the full line is subtracted. The result is modulo 100. If the result is negative, it is reflected using:

new_id = 100 - (abs(id) + 1)

Step 6: Positional Noise Note: this might be removed due to decoding issues

Each character is adjusted based on the remaining characters in the line:

  • Calculate the average ID of the following characters,
  • Multiply by 2 and mod 100,
  • Add this value to the current ID, then subtract ⌊id/2⌋,
  • Apply modulo 100 and update the character accordingly.

HARD-Encoder

The HARD-encoder makes decoding exponentially harder by transforming the EASY-encoded string further through chaotic mutations.

Step 1: Xorshift Scramble

Each character ID is transformed using:

((id >> 19) << 11 >> 3) % 100

Step 2: Contextual Mutation (non-dynamic)

For each character c:

Let id_bef = ID of previous character (or 0),

Let id_aft = ID of next character (or 0), Compute:

new_id = (id - id_bef) % 50 + id_aft * ((id - id_bef) % 20)

  • Then new_id = new_id % 100

Step 3: Compiler Correction Pass

To prevent EASY-encoded bugs, adjust for line offsets:

new_id = (id + line_number - total_char_count) % 100

If result is negative:

new_id = 100 - (abs(new_id) + 1)

FINAL_ENCODE

This final obfuscation step might becomed optional but is always encouraged to fully "xH311-ify" the code. Each character is passed through a chaotic sum function with 59:

crazy_sum(a, 59) = ((a * 37) + (59 * 19) + (a ^ 59)) % 60

new_id = crazy_sum + 1

The resulting ID is then mapped back to a final character.

Notes

The EASY-encoder is primarily intended for human authorship.

Only the output of the FINAL_ENCODE can be compiled.

Any corruption in the encoder stages can lead to random behavior, memory leaks, or spontaneous program deletion (by design). The language embraces chaos: predictability is a bug.

5.0 Notes

Here are some key notes made to encourage and help people:

  • It uses Base-60. For now its just 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwx (59 chars to represent them)
  • There is no interpreter or compiler yet (help with either would be greatly appreciated)
  • Don't even try using this language
  • If a decoder is impossible, remove the impossible making components (but add new decodable encoding-steps to keep it chaotic >:) )
  • I made this with the help of ChatGPT (built on the encoding base-line I came up with, but still under my command -> yes this encoder is so hard to make I needed an AI for it, and I didn't have time to work 8 hours daily on one so... atleast we got a half-done one, right?)
  • The python code will later be found under my uploads (hopefully)
  • A decoder is in the works, but I might upload an AI generated base-line for one (so you fellow programmers can try yourself at one)