CPU-x86_64-InstructionWriter

 view release on metacpan or  search on metacpan

lib/CPU/x86_64/InstructionWriter.pm  view on Meta::CPAN

  my $label= $writer->get_label($name); # label-by-name, created on demand
  my $label= $writer->get_label();      # new anonymous label

Return a label object for the given name, or if no name is given, return an anonymous label.
Names beginning with period "." will be prefixed by the current value of L</scope>.

The label objects returned can be assigned a location within the instruction stream using L</mark>
and used as the target for C<JMP> and C<JMP>-like instructions.  A label can also be used as a
constant once all variable-length instructions have been L</resolve>d and once L</start_address>
is defined.

=head2 label

  ->label($label_ref)     # bind label object to current position
  ->label(my $new_label)  # like above, but create anonymous label object and assign to $new_label
  ->label($label_name)    # like above, but create/lookup label object by name

Bind a named label to the current position in the instruction buffer.  You can also pass a label
reference from L</get_label>, or an undef variable which will be assigned a label.

If the current position follows instructions of unknown length, the label will be processed as an
unknown, and shift automatically as the instructions are resolved.

=head2 bytes

Return the assembled instructions as a string of bytes.  This will fail if any of the labels were
left un-marked or if any expressions can't be evaluated.

=head2 append

Append all instructions, labels, and unknowns of another InstructionWriter to the instructions
of this writer.  These are copied, and do not retain references to the original writer.
Any label in the other writer which begins with '.' (meaning the other writer's L<scope> was
the empty string) will be renamed into the current C<scope>.  Other label names are copied
as-is.  Labels which are anchored to the L<start_address> of the previous writer get an offset
applied to anchor them in terms of this writer's C<start_address>.

=head1 DATA DECLARATION

This class assembles instructions, but sometimes you want to mix in data, and label the data.
These methods append data, optionally aligned.

=head2 align, align16, align32, align64, align128

Append zero or more bytes so that the next instruction is aligned in memory.
By default, the fill-byte will be a NO-OP (0x90).  You can override it with your choice.

=head2 data

  $writer->data("\x01");
  my %set= (
    "\x01\x02\x03\x04" => $writer->new_label,
    "\x03\x04"         => undef,
    ...
  );
  $writer->data(\%set);

Append a string of literal bytes to the instruction stream.

If the value is a hashref, each key of the hashref will be added, and each value of the hashref
will be a label that is anchored to the start of those bytes.  If your hashref keys are unicode
strings, use L<data_str> instead.  This also looks for opportunities to overlap strings if one
is a subset of another.

=head2 data_i8, data_i16, data_i32, data_i64

Pack an integer into some number of bits and append it.

=head2 data_f32, data_f64

Pack a floating point number into the given bit-length (float or double) and append it.

=head2 data_str

  $writer->data_str($text, encoding => 'UTF-8', nul_terminate => 1);
  $writer->data_str(\%string_set, encoding => 'UTF-8', nul_terminate => 1);

Append a string, and deal with encoding.  This differs from ->data in that it checks for
nonascii characters in the string, and encodes them in the specified encoding, defaulting to
UTF-8.  It also includes a trailing NUL character unless you override that option.

=head1 INSTRUCTIONS

The following methods append an instruction to the buffer, and return C<$self> so you can continue
calling instructions in a chain.

=head2 CPUID

=over

=item cpuid

Uses EAX as a parameter, and clobbers EAX, EBX, ECX, and EDX with cpu information

=back

=head2 NOP, PAUSE

Insert one or more no-op instructions.

=over

=item nop(), C<nop( $n )>

If called without an argument, insert one no-op.  Else insert C<$n> no-ops.

=item pause(), C<pause( $n )>

Like NOP, but hints to the processor that the program is in a spin-loop so it
has the opportunity to reduce power consumption.  This is a 2-byte instruction.

=back

=head2 CALL

=over

=item C<call_label( $label )>

Call to subroutine at named label, relative to current RIP.
This method takes a label and calculates a C<call_rel( $ofs )> for you.



( run in 0.742 second using v1.01-cache-2.11-cpan-cdf2f3d4e48 )