Ad Space — Top Banner

E2147

Delphi Programming Language

Severity: Moderate

What Does This Error Mean?

Error E2147 means you tried to use a variable or type in an inline assembly (asm) block that is not supported in that context. Inline assembly works directly with CPU registers and memory addresses. Certain Delphi types — like strings, dynamic arrays, interfaces, and some structured types — require runtime management that cannot happen inside an asm block.

Affected Models

  • Delphi 2005 and later (32-bit)
  • RAD Studio 32-bit targets
  • Not applicable to 64-bit Delphi (which has different asm rules)

Common Causes

  • Trying to directly access a managed type (string, dynamic array, interface) in an asm block
  • Using a variable-length or reference-counted type that Delphi manages automatically
  • Accessing a class instance or object reference directly inside asm code
  • Using an open array parameter or variant inside an asm block
  • Referencing a variable that is optimized into a register and has no memory address

How to Fix It

  1. Move the managed variable out of the asm block. Assign it to a local integer or pointer variable first, then use that in the asm block.

    Example: instead of accessing a string directly in asm, get its pointer with PChar(MyString) first and use that pointer.

  2. For string access, use PChar(MyString) to get a raw pointer to the character data. A PChar is just a memory address and is safe to use in asm.

    Be careful: modifying string data through a raw pointer bypasses Delphi's reference counting. Make sure you know what you are doing.

  3. If you need to pass the length or data of a dynamic array to asm, use Length() to get the count and use a pointer (Pointer(MyArray)) to get the base address.

    Dynamic arrays in Delphi have a header before the data. The array variable itself holds a pointer to the first element.

  4. If possible, refactor the code so all managed-type operations happen before the asm block, and only basic integers, floats, and raw pointers are used inside asm.

    This makes the asm block simpler and avoids E2147 entirely.

  5. Consider replacing the inline assembly with equivalent Pascal code. Delphi's compiler with optimizations enabled produces very efficient code. In many cases pure Pascal is fast enough.

    Use {$O+} to enable optimizations. Modern CPUs are very efficient at the code Delphi generates.

When to Call a Professional

E2147 is something you can fix yourself if you are comfortable with low-level code. If you are new to inline assembly, consider rewriting the logic in pure Pascal instead — modern Delphi compilers optimize Pascal code very well. Only use inline assembly when you truly need specific CPU instructions that Pascal cannot express.

Frequently Asked Questions

When should I actually use inline assembly in Delphi?

Almost never, unless you need specific CPU instructions not available in Pascal — like SIMD (SSE/AVX) instructions for image processing or cryptography. For general programming, modern Delphi compilers produce excellent machine code. Use intrinsics (like those in System.Types) before resorting to raw asm.

Does Delphi 64-bit support inline assembly?

Yes, but with more restrictions than 32-bit. Delphi 64-bit uses a different calling convention (x64) and the asm block rules are stricter. Some code that works in 32-bit asm needs significant rewriting for 64-bit. Embarcadero recommends minimizing inline assembly for cross-platform compatibility.

Is inline assembly in Delphi the same as writing pure assembly language?

It is similar but with some integration with Delphi's variable system. You can reference Delphi variables by name inside asm blocks. But you have to be careful about calling conventions, register use, and exception handling — the compiler has expectations about which registers are preserved.