I realized that this was an assembler/disassembler, as I understood it, ported from C, but I still did not find any products in the ZydisB catalog, which, according to the line of the assembler procedure, gives me a sequence of x64 opcodes.
I'll comment one of the examples for you and contrast it with the code in your original post.
The following is the listing for the EncodeMovA example:
{ --------------------------------------------------------------------------- }
{ @file }
{ Demonstrates encoding a single instruction using the encoder. }
{$APPTYPE CONSOLE}
{$TYPEDADDRESS ON}
{$LONGSTRINGS OFF}
{$WRITEABLECONST OFF}
{ --------------------------------------------------------------------------- }
program EncodeMovA;
uses
ZyDis,
winapi
;
{$include Z900_zydis_inlines.inc}
{ --------------------------------------------------------------------------- }
var
req : ZydisEncoderRequest;
encoded_instruction : array[ZYDIS_MAX_INSTRUCTION_RANGE] of ZyanU8;
encoded_length : ZyanUSize = sizeof(encoded_instruction);
i : integer; { can't initialize "for" loop variables!! }
sprintf_buffer : packed array[0..511] of char = #0;
begin
RtlZeroMemory(@req, sizeof(req));
RtlZeroMemory(@encoded_instruction, sizeof(encoded_instruction));
with req do
begin
mnemonic := ZYDIS_MNEMONIC_MOV;
machine_mode := ZYDIS_MACHINE_MODE_LONG_64;
operand_count := 2;
operands[0].&type := ZYDIS_OPERAND_TYPE_REGISTER;
operands[0].reg.value := ZYDIS_REGISTER_RAX;
operands[1].&type := ZYDIS_OPERAND_TYPE_IMMEDIATE;
operands[1].imm.u := $1337;
end;
repeat { scope, not a loop }
if ZYAN_FAILED
(
ZydisEncoderEncodeInstruction
(
@req, encoded_instruction, @encoded_length
)
) then
begin
writeln('Failed to encode instruction');
break;
end;
for i := 0 to encoded_length - 1 do
begin
{ output the bytes that make up the instruction }
sprintf(sprintf_buffer, '%02X ', encoded_instruction[i]);
write(sprintf_buffer);
end;
writeln;
until TRUE; { end of scope }
writeln;
writeln;
writeln('press ENTER/RETURN to end this program');
readln;
end.
In your original post, the execute function uses a list of bytes (basically binary instructions) to be executed.
Zydis is higher level than that. You give Zydis a _description_ of the instruction you wish to obtain the encoding for and Zydis will return the bytes that are the binary representation of that instruction. In the example above, the instruction that is being encoded is "mov rax, $1337"
That's why the mnemonic is "...MOV"
the machine mode "...LONG_64"
the operand count is 2 because there is a source operand and a destination operand.
the first operand is a register (rax) "...TYPE_REGISTER"
the register is rax "...REGISTER_RAX"
the second operand is an immediate value "...TYPE_IMMEDIATE"
the value is "$1337"
Using Zydis it is possible to write an assembler. It certainly is more convenient than manually figuring out the binary representation of every instruction.
The EncodeFromScratchA example is an example of assembling more than 1 instruction _and_ then executing the resulting stream of bytes.
Essentailly, as long as you know assembly, it's easy to describe the instruction to Zydis, which will assemble it for you and once that is done, it's ready for execution. You could even have the user type assembler, assemble it on the fly then execute it, all without leaving the program that accepts assembly instructions (a bit like a Turbo Pascal IDE but, for assembler...) IOW, you can generate executable code on the fly and execute immediately after it has been generated (which I believe is what you want to do.)