Nasm-X86

 view release on metacpan or  search on metacpan

lib/Nasm/X86.pm  view on Meta::CPAN

 {my ($fdes) = @_;                                                              # File descriptor
  @_ == 1 or confess;
  Comment "Close a file";
  SaveFirstFour;
  Mov rdi,$fdes;
  Mov rax,3;
  Syscall;
  RestoreFirstFourExceptRax;
 }

sub StatSize()                                                                  # Stat a file whose name is addressed by rax to get its size in rax
 {@_ == 0 or confess;
  Comment "Stat a file for size";
  my $S = extractCStructure "#include <sys/stat.h>";                            # Get location of size field
  my $Size = $$S{stat}{size};
  my $off  = $$S{stat}{fields}{st_size}{loc};

  SaveFirstFour;
  Mov rdi, rax;                                                                 # File name
  Mov rax,4;
  Lea rsi, "[rsp-$Size]";
  Syscall;
  Mov rax, "[$off+rsp-$Size]";                                                  # Place size in rax
  RestoreFirstFourExceptRax;
 }

sub ReadFile()                                                                  # Read a file whose name is addressed by rax into memory.  The address of the mapped memory and its length are returned in registers rax,rdi
 {@_ == 0 or confess;
  Comment "Read a file into memory";

  SaveFirstSeven;                                                               # Generated code
  my ($local, $file, $addr, $size, $fdes) = AllocateAll8OnStack 4;                     # Local data

  Mov $file, rax;                                                               # Save file name

  StatSize;                                                                     # File size
  Mov $size, rax;                                                               # Save file size

  Mov rax, $file;                                                               # File name
  OpenRead;                                                                     # Open file for read
  Mov $fdes, rax;                                                               # Save file descriptor

  my $d  = extractMacroDefinitionsFromCHeaderFile "linux/mman.h";               # mmap constants
  my $pa = $$d{MAP_PRIVATE};
  my $ro = $$d{PROT_READ};

  Mov rax, 9;                                                                   # mmap
  Mov rsi, $size;                                                               # Amount of memory
  Xor rdi, rdi;                                                                 # Anywhere
  Mov rdx, $ro;                                                                 # Read write protections
  Mov r10, $pa;                                                                 # Private and anonymous map
  Mov r8,  $fdes;                                                               # File descriptor for file backing memory
  Mov r9,  0;                                                                   # Offset into file
  Syscall;
  Mov rdi, $size;
  RestoreFirstSevenExceptRaxAndRdi;
 }

#D1 Strings                                                                     # Operations on Strings

sub CreateByteString()                                                          # Create an relocatable string of bytes in an arena and returns its address in rax
 {@_ == 0 or confess;
  Comment "Create byte string";
  my $N = 4096;                                                                 # Initial size of string

  my ($string, $size, $used, $data) = All8Structure rax, 3;                     # String base

  my $sub = S                                                                   # Create string
   {SaveFirstFour;
    Mov rax, $N;
    AllocateMemory;
    ClearRegisters rdi;
    Mov $used, rdi;
    Mov rdi, $N;
    Mov $size, rdi;

    RestoreFirstFourExceptRax;
   } name=> "CreateByteString";

  Call $sub;

  genHash("ByteString",                                                         # Definition of byte string
    structure => $string,                                                       # Structure details
    size      => $size,                                                         # Size field details
    used      => $used,                                                         # Used field details
    data      => $data,                                                         # The first 8 bytes of the data
   );
 }

sub ByteString::m($)                                                            # Append the content with length rdi addressed by rsi to the byte string addressed by rax
 {my ($byteString) = @_;                                                        # Byte string descriptor
  my $size = $byteString->size;
  my $used = $byteString->used;
  my $data = $byteString->data;
  my $target = rdx;                                                             # Register that addresses target of move
  my $length = rdx;                                                             # Register used to update used field

  SaveFirstFour;
  Lea $target, $data;                                                           # Address of data field
  Add $target, $used;                                                           # Skip over used data

  PushR rax;                                                                    # Save address of byte string
  Mov rax, $target;                                                             # Address target
  CopyMemory;                                                                   # Move data in
  PopR rax;                                                                     # Restore address of byte string

  Mov $length, $used;                                                           # Update used field
  Add $length, rdi;
  Mov $used, $length;

  RestoreFirstFour;
 }

sub ByteString::copy($)                                                         # Append the byte string addressed by rdi to the byte string addressed by rax
 {my ($byteString) = @_;                                                        # Byte string descriptor
  my $used = $byteString->used =~ s(rax) (rdx)r;
  my $data = $byteString->data =~ s(rax) (rdx)r;

  SaveFirstFour;
  Mov rdx, rdi;                                                                 # Address byte string to be copied
  Mov rdi, $used;

lib/Nasm/X86.pm  view on Meta::CPAN

    Start;                                                                        # Start the program
    Mov rax, Rs($0);                                                              # File to stat
    OpenRead;                                                                     # Open file
    PrintOutRegisterInHex rax;

    Close(rax);                                                                   # Close file  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    PrintOutRegisterInHex rax;
    Exit;                                                                         # Return to operating system
    my $r = Assemble;
    ok $r =~ m(( 0000){3} 0003)i;                                                 # Expected file number
    ok $r =~ m(( 0000){4})i;                                                      # Expected file number


=head2 StatSize()

Stat a file whose name is addressed by rax to get its size in rax


B<Example:>


    Start;                                                                        # Start the program
    Mov rax, Rs($0);                                                              # File to stat

    StatSize;                                                                     # Stat the file  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    PrintOutRegisterInHex rax;
    Exit;                                                                         # Return to operating system
    my $r = Assemble =~ s( ) ()gsr;
    if ($r =~ m(rax:([0-9a-f]{16}))is)                                            # Compare file size obtained with that from fileSize()
     {is_deeply $1, sprintf("%016X", fileSize($0));
     }


=head2 ReadFile()

Read a file whose name is addressed by rax into memory.  The address of the mapped memory and its length are returned in registers rax,rdi


B<Example:>


    Start;                                                                        # Start the program
    Mov rax, Rs($0);                                                              # File to read

    ReadFile;                                                                     # Read file  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    PrintOutMemory;                                                               # Print memory
    Exit;                                                                         # Return to operating system
    my $r = Assemble;                                                             # Assemble and execute
    ok index($r =~ s([^0x0-0x7f]) ()gsr, readFile($0) =~ s([^0x0-0x7f]) ()gsr)>-1;# Output contains this file


=head1 Strings

Operations on Strings

=head2 CreateByteString()

Create an relocatable string of bytes in an arena and returns its address in rax


B<Example:>


    Start;                                                                        # Start the program
    my $q = Rs my $t = 'ab';

    my $s = CreateByteString;                                                     # Create a string  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    Mov rsi, $q;                                                                  # Address of memory to copy
    Mov rdi, length $t;                                                           # Length of memory  to copy
    $s->m;                                                                        # Copy memory into byte string

    Mov rdi, rax;                                                                 # Save source byte string

    CreateByteString;                                                             # Create target byte string  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    $s->copy;                                                                     # Copy source to target

    Xchg rdi, rax;                                                                # Swap source and target byte strings
    $s->copy;                                                                     # Copy source to target
    Xchg rdi, rax;                                                                # Swap source and target byte strings
    $s->copy;
    Xchg rdi, rax;
    $s->copy;
    Xchg rdi, rax;
    $s->copy;

    $s->out;                                                                      # Print byte string

    Exit;                                                                         # Return to operating system
    Assemble =~ m(($t x 8));                                                      # Assemble and execute


=head2 ByteString::m($byteString)

Append the content with length rdi addressed by rsi to the byte string addressed by rax

     Parameter    Description
  1  $byteString  Byte string descriptor

=head2 ByteString::copy($byteString)

Append the byte string addressed by rdi to the byte string addressed by rax

     Parameter    Description
  1  $byteString  Byte string descriptor

=head2 ByteString::out($byteString)

Print the specified byte string addressed by rax on sysout

     Parameter    Description
  1  $byteString  Byte string descriptor

=head1 Assemble

Assemble generated code

lib/Nasm/X86.pm  view on Meta::CPAN


=head2 Assemble(%options)

Assemble the generated code

     Parameter  Description
  1  %options   Options


=head1 Private Methods

=head2 Label()

Create a unique label


=head2 Dbwdq($s, @d)

Layout data

     Parameter  Description
  1  $s         Element size
  2  @d         Data to be laid out

=head2 Rbwdq($s, @d)

Layout data

     Parameter  Description
  1  $s         Element size
  2  @d         Data to be laid out


=head1 Index


1 L<All8Structure|/All8Structure> - Create a structure consisting of 8 byte fields

2 L<AllocateAll8OnStack|/AllocateAll8OnStack> - Create a local data descriptor consisting of the specified number of 8 byte local variables and return an array: (local data descriptor,  variable definitions.

3 L<AllocateMemory|/AllocateMemory> - Allocate the amount of memory specified in rax via mmap and return the address of the allocated memory in rax

4 L<Assemble|/Assemble> - Assemble the generated code

5 L<ByteString::copy|/ByteString::copy> - Append the byte string addressed by rdi to the byte string addressed by rax

6 L<ByteString::m|/ByteString::m> - Append the content with length rdi addressed by rsi to the byte string addressed by rax

7 L<ByteString::out|/ByteString::out> - Print the specified byte string addressed by rax on sysout

8 L<ClearMemory|/ClearMemory> - Clear memory - the address of the memory is in rax, the length in rdi

9 L<ClearRegisters|/ClearRegisters> - Clear registers by setting them to zero

10 L<Close|/Close> - Close a file descriptor

11 L<Comment|/Comment> - Insert a comment into the assembly code

12 L<CopyMemory|/CopyMemory> - Copy memory, the target is addressed by rax, the length is in rdi, the source is addressed by rsi

13 L<CreateByteString|/CreateByteString> - Create an relocatable string of bytes in an arena and returns its address in rax

14 L<Db|/Db> - Layout bytes in the data segment and return their label

15 L<Dbwdq|/Dbwdq> - Layout data

16 L<Dd|/Dd> - Layout double words in the data segment and return their label

17 L<Dq|/Dq> - Layout quad words in the data segment and return their label

18 L<Ds|/Ds> - Layout bytes in memory and return their label

19 L<Dw|/Dw> - Layout words in the data segment and return their label

20 L<Exit|/Exit> - Exit with the specified return code or zero if no return code supplied

21 L<For|/For> - For

22 L<Fork|/Fork> - Fork

23 L<FreeMemory|/FreeMemory> - Free memory via mmap.

24 L<GetPid|/GetPid> - Get process identifier

25 L<GetPPid|/GetPPid> - Get parent process identifier

26 L<GetUid|/GetUid> - Get userid of current process

27 L<If|/If> - If

28 L<Label|/Label> - Create a unique label

29 L<LocalData|/LocalData> - Map local data

30 L<LocalData::allocate8|/LocalData::allocate8> - Add some 8 byte local variables and return an array of variable definitions

31 L<LocalData::free|/LocalData::free> - Free a local data area on the stack

32 L<LocalData::start|/LocalData::start> - Start a local data area on the stack

33 L<LocalData::variable|/LocalData::variable> - Add a local variable

34 L<LocalVariable::stack|/LocalVariable::stack> - Address a local variable on the stack

35 L<OpenRead|/OpenRead> - Open a file, whose name is addressed by rax, for read and return the file descriptor in rax

36 L<PeekR|/PeekR> - Peek at register on stack

37 L<PopR|/PopR> - Pop registers from the stack

38 L<PrintOutMemory|/PrintOutMemory> - Print the memory addressed by rax for a length of rdi

39 L<PrintOutMemoryInHex|/PrintOutMemoryInHex> - Dump memory from the address in rax for the length in rdi

40 L<PrintOutNl|/PrintOutNl> - Write a new line

41 L<PrintOutRaxInHex|/PrintOutRaxInHex> - Write the content of register rax to stderr in hexadecimal in big endian notation

42 L<PrintOutRaxInReverseInHex|/PrintOutRaxInReverseInHex> - Write the content of register rax to stderr in hexadecimal in little endian notation

43 L<PrintOutRegisterInHex|/PrintOutRegisterInHex> - Print any register as a hex string



( run in 0.435 second using v1.01-cache-2.11-cpan-5511b514fd6 )