5

It’s well known for assembly coders in Delphi that any fields of a record, class etc. can be accessed from an asm code routine as shown in the example below:

type 

THeader = packed record
  field1: uint64;
  field2: uint32;
end;

(* some code here *)

asm
  mov rax, [rcx + THeader.field1]
  mov edx, [rcx + THeader.field2]
end;

But what if – as the name suggests – this is just a header of a big, unpredictable sized data stream and I want to access the actual start position of the data stream (that is, the first byte after the header)? A simple solution might be the one shown below (but I prefer something less unnatural, without defining a constant):

type

  THeader = packed record
    field1: uint64;
    field2: uint32;
  end;
  (* start_of_data_stream: byte; *)

const 
  SIZEOFTHEADER = sizeof(THeader);

(* some code here *)

asm
  mov al, [rcx + SIZEOFTHEADER] (* [rcx + THeader.start_of_data_stream] *)
end;

Any better ideas, maybe?

3
  • 1
    Not sure this warranted the d/vote. Commented Jan 22, 2020 at 13:02
  • 1
    BTW, in C you can do this without inline asm, with a flexible array member at the end of a struct. But if you are going to use asm, prefer movzx eax, byte [rcx + ...] for loading a single byte on modern CPUs. Merging into the low byte of an existing register (mov to AL) can be more expensive than a zero-extending load (movzx) Commented Jan 22, 2020 at 13:16
  • @PeterCordes Need Delphi and definitely asm for this particular purpose, so I have no choice here. Anyway, thanks for the zero extending load remark, at least this surely deserves an upvote. Commented Jan 22, 2020 at 13:50

1 Answer 1

9

You can use TYPE(typename) to find the size of the type in an asm expression. For example:

mov al, [rcx + TYPE(THeader)]

This (together with a number of other useful operators) is documented: http://docwiki.embarcadero.com/RADStudio/en/Assembly_Expressions#Expression_Operators

Sign up to request clarification or add additional context in comments.

4 Comments

Note that I did not know that this operator existed until I read the documentation.
Right answer. Short, elegant. period.
Reading that page: "Numeric constants must be integers, and their values must be between 2,147,483,648 and 4,294,967,295." Looks like they dropped a -.
@Brian indeed, and I bet that they also forgot to update it to account for 64 bit

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.