This guide is designed to help you understand how to encode different types of numbers—like integers, floats, and doubles—and specific commands such as NOPs, true, and false in both ARM and ARM64 architectures.
Each example includes the hexadecimal machine code and a clear description of what the code does, specifically tailored for game developers and enthusiasts looking to modify games or dive into low-level programming.
ARM Architecture (ARMv7)
Integers
Here’s how to set integer values in ARM:
mov r0, #1 // Sets r0 to 1
// Hexadecimal: 01 00 A0 E3 1E FF 2F E1 // This hex value is number 1 in integer
mov r0, #2 // Sets r0 to 2
// Hexadecimal: 02 00 A0 E3 1E FF 2F E1 // This hex value is number 2 in integer
D5 09 A9 E3 1E FF 2F E1 // Encodes 4,000,000
12 07 80 E3 1E FF 2F E1 // Encodes 12,000,000
DC 0F 00 E3 1E FF 2F E1 // Encodes 4,060
DC 0F 0F E3 1E FF 2F E1 // Encodes 120,000
01 06 A0 E3 1E FF 2F E1 // Encodes 1,000,000
DC 0F F9 E3 1E FF 2F E1 // Encodes -800
DC 0D F7 E3 1E FF 2F E1 // Encodes -14,000
DC 0C F7 E3 1E FF 2F E1 // Encodes -56,000
Floats
To encode floating point numbers, ARM uses VFP (Vector Floating Point) instructions:
vmov.f32 s0, #2.0 // Sets s0 to float 2.0
// Hexadecimal: 00 00 A0 F2 1E FF 2F E1 // This hex value is number 2.0 in float
vmov.f32 s0, #10.0 // Sets s0 to float 10.0
// Hexadecimal: 00 00 A0 F2 1E FF 2F E1 // This hex value is number 10.0 in float
00 00 40 E3 1E FF 2F E1 // Is 0 as a float
F9 04 44 E3 1E FF 2F E1 // Is a high floating-point value
CC 0D 43 E3 1E FF 2F E1 // Is 0.5 as a float
48 02 44 E3 1E FF 2F E1 // Is 50 as a float
80 0F 43 E3 1E FF 2F E1 // Is 1 as a float
80 0D 44 E3 1E FF 2F E1 // Is a very high floating-point value
9D 04 47 E3 1E FF 2F E1 // Is a very big floating number
Doubles
Doubles are handled similarly but use double precision registers:
vmov.f64 d0, #1.0 // Sets d0 to double 1.0
// Hexadecimal: 00 00 B0 F2 1E FF 2F E1 // This hex value is number 1.0 in double
vmov.f64 d0, #2.0 // Sets d0 to double 2.0
// Hexadecimal: 00 00 B0 F2 1E FF 2F E1 // This hex value is number 2.0 in double
vmov.f64 d0, #0.0 // Sets d0 to double 0.0
// Hexadecimal: 00 00 00 00 00 00 00 00 EB 03 5F E1 // Encodes double 0
vmov.f64 d0, #1000.0 // Sets d0 to double 1000.0
// Hexadecimal: 00 00 00 00 00 40 8F 40 EB 03 5F E1 // Encodes double 1000
vmov.f64 d0, #10000.0 // Sets d0 to double 10000.0
// Hexadecimal: 00 00 00 00 00 C0 1C 46 EB 03 5F E1 // Encodes double 10000
vmov.f64 d0, #-500.0 // Sets d0 to double -500.0
// Hexadecimal: 00 00 00 00 00 80 87 C0 EB 03 5F E1 // Encodes double -500
vmov.f64 d0, #1000000.0 // Sets d0 to double 1,000,000.0
// Hexadecimal: 00 00 00 00 00 40 0F 49 EB 03 5F E1 // Encodes double 1,000,000
Long Values
// Encoding 0
mov r0, #0 // Sets r0 to 0
// Hexadecimal: 00 00 A0 E3 1E FF 2F E1
// Encoding 1
mov r0, #1 // Sets r0 to 1
// Hexadecimal: 01 00 A0 E3 1E FF 2F E1
// Encoding a high number (example: 1,234,567,890)
mov r0, #0x4996; movt r0, #0x49F1 // Sets r0 to 1,234,567,890
// Hexadecimal for mov: 96 49 A0 E3 1E FF 2F E1; Hexadecimal for movt: F1 49 A0 E3 1E FF 2F E1
// Encoding -1 (Negative One)
mvn r0, #0 // Sets r0 to -1 (mvn is "move not", which inverts the bits of 0)
// Hexadecimal: 00 00 E0 E3 1E FF 2F E1
ARM64 Architecture (AArch64)
Integers
Setting integers in ARM64:
mov x0, #1 // Sets x0 to 1
// Hexadecimal: 20 00 80 D2 C0 03 5F D6 // This hex value is number 1 in integer
mov x0, #2 // Sets x0 to 2
// Hexadecimal: 40 00 80 D2 C0 03 5F D6 // This hex value is number 2 in integer
00 E0 AF D2 C0 03 5F D6 // Encodes a high integer value
00 00 80 D2 C0 03 5F D6 // Encodes "false", integer value 0
20 00 80 D2 C0 03 5F D6 // Encodes "true", integer value 1
1F 20 03 D5 C0 03 5F D6 // NOP (No Operation)
E0 69 98 92 C0 03 5F D6 // Encodes -50,000 as a signed integer
00 02 A0 D2 C0 03 5F D6 // Encodes 100,000
40 00 80 D2 C0 03 5F D6 // Encodes 2
60 00 80 D2 C0 03 5F D6 // Encodes 3
E0 1F 80 D2 C0 03 5F D6 // Encodes 255
00 7D 80 D2 C0 03 5F D6 // Encodes 1,000
Floats
Floating point numbers in ARM64:
fmov s0, #2.0 // Sets s0 to float 2.0
// Hexadecimal: 00 08 81 1E C0 03 5F D6 // This hex value is number 2.0 in float
fmov s0, #10.0 // Sets s0 to float 10.0
// Hexadecimal: 00 50 81 1E C0 03 5F D6 // This hex value is number 10.0 in float
fmov s0, #0.0 // Sets s0 to float 0.0
// Hexadecimal: 00 00 00 00 D0 03 5F D6 // This hex value encodes float 0
fmov s0, #1.0 // Sets s0 to float 1.0
// Hexadecimal: 00 00 80 3F D0 03 5F D6 // This hex value encodes float 1
fmov s0, #100.0 // Sets s0 to float 100.0
// Hexadecimal: 00 00 C8 42 D0 03 5F D6 // This hex value encodes float 100
fmov s0, #3000.0 // Sets s0 to float 3000.0
// Hexadecimal: 00 00 5A 45 D0 03 5F D6 // This hex value encodes float 3000
Doubles
Encoding doubles in ARM64:
fmov d0, #1.0 // Sets d0 to double 1.0
// Hexadecimal: 00 08 C1 1E C0 03 5F D6 // This hex value is number 1.0 in double
fmov d0, #2.0 // Sets d0 to double 2.0
// Hexadecimal: 00 10 C1 1E C0 03 5F D6 // This hex value is number 2.0 in double
fmov d0, #0.0 // Sets d0 to double 0.0
// Hexadecimal: 00 00 00 00 00 00 00 00 D0 03 5F D6 // Encodes double 0
fmov d0, #1000.0 // Sets d0 to double 1000.0
// Hexadecimal: 00 00 00 00 00 40 8F 40 D0 03 5F D6 // Encodes double 1000
fmov d0, #10000.0 // Sets d0 to double 10000.0
// Hexadecimal: 00 00 00 00 00 C0 1C 46 D0 03 5F D6 // Encodes double 10000
fmov d0, #-500.0 // Sets d0 to double -500.0
// Hexadecimal: 00 00 00 00 00 80 87 C0 D0 03 5F D6 // Encodes double -500
fmov d0, #1000000.0 // Sets d0 to double 1,000,000.0
// Hexadecimal: 00 00 00 00 00 40 0F 49 D0 03 5F D6 // Encodes double 1,000,000
NOP, True, False
Special instructions and Boolean values:
// ARMv7 NOP
nop // Does nothing
// Hexadecimal: 00 F0 20 E3 C0 03 5F D6 // NOP operation
// ARMv7 True (set as 1)
mov r0, #1
// Hexadecimal: 01 00 A0 E3 C0 03 5F D6 // This hex value is True
// ARMv7 False (set as 0)
mov r0, #0
// Hexadecimal: 00 00 A0 E3 C0 03 5F D6 // This hex value is False
// ARM64 NOP
nop // Does nothing
// Hexadecimal: 1F 20 03 D5 C0 03 5F D6 // NOP operation
// ARM64 True (set as 1)
mov x0, #1
// Hexadecimal: 20 00 80 D2 C0 03 5F D6 // This hex value is True
// ARM64 False (set as 0)
mov x0, #0
// Hexadecimal: E0 03 1F AA C0 03 5F D6 // This hex value is False
Long Values
// Encoding 0
mov x0, #0 // Sets x0 to 0
// Hexadecimal: 00 00 80 D2 C0 03 5F D6
// Encoding 1
mov x0, #1 // Sets x0 to 1
// Hexadecimal: 01 00 80 D2 C0 03 5F D6
// Encoding a high number (example: 1,234,567,890)
mov x0, #1234567890 // Directly sets x0 to 1,234,567,890 in one instruction
// Hexadecimal: D2 02 96 92 C0 03 5F D6
// Encoding -1 (Negative One)
movn x0, #0 // Sets x0 to -1 (movn is "move negative", which moves the bitwise NOT of 0)
// Hexadecimal: 00 00 80 F2 C0 03 5F D6
Conclusion
This guide offers a foundational understanding of how to encode various types of data and operations in ARM and ARM64 architectures, with specific attention to their application in game modifications. Each example is carefully explained with its corresponding hexadecimal representation to ensure clarity and practical application.