Name

Nasm::X86 - Generate Nasm assembler code

Synopsis

Write and run some assembler code to start a child process and wait for it, printing out the process identifiers of each process involved:

Start;                                                                        # Start the program
Fork;                                                                         # Fork

Test rax,rax;
If                                                                            # Parent
 {Mov rbx, rax;
  WaitPid;
  PrintOutRegisterInHex rax;
  PrintOutRegisterInHex rbx;
  GetPid;                                                                     # Pid of parent as seen in parent
  Mov rcx,rax;
  PrintOutRegisterInHex rcx;
 }
sub                                                                           # Child
 {Mov r8,rax;
  PrintOutRegisterInHex r8;
  GetPid;                                                                     # Child pid as seen in child
  Mov r9,rax;
  PrintOutRegisterInHex r9;
  GetPPid;                                                                    # Parent pid as seen in child
  Mov r10,rax;
  PrintOutRegisterInHex r10;
 };

Exit;                                                                         # Return to operating system

my $r = assemble();

#    r8: 0000 0000 0000 0000   #1 Return from fork as seen by child
#    r9: 0000 0000 0003 0C63   #2 Pid of child
#   r10: 0000 0000 0003 0C60   #3 Pid of parent from child
#   rax: 0000 0000 0003 0C63   #4 Return from fork as seen by parent
#   rbx: 0000 0000 0003 0C63   #5 Wait for child pid result
#   rcx: 0000 0000 0003 0C60   #6 Pid of parent

Get the size of a file:

Start;                                                                        # Start the program
my $f = Rs($0);                                                               # File to stat
StatSize($f);                                                                 # 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));
 }

Installation

You will need the Intel Software Development Emulator and the Networkwide Assembler installed on your test system. For full details of how to do this see: https://github.com/philiprbrenan/NasmX86/blob/main/.github/workflows/main.yml

Description

Generate Nasm assembler code

Version "202104011".

The following sections describe the methods in each functional area of this module. For an alphabetic listing of all methods by name see Index.

Generate Network Assembler Code

Generate assembler code that can be assembled with Nasm

SetLabel($l)

Set a label in the code section

   Parameter  Description
1  $l         Label

Start()

Initialize the assembler

Example:

  Start;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

  PrintOutString "Hello World";
  Exit;
  ok assemble =~ m(Hello World);

Ds(@d)

Layout bytes in memory and return their label

   Parameter  Description
1  @d         Data to be laid out

Example:

  Start;
  my $q = Rs('a'..'z');

  my $d = Ds('0'x64);                                                           # Output area  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

  Vmovdqu32(xmm0, "[$q]");                                                      # Load
  Vprolq   (xmm0,   xmm0, 32);                                                  # Rotate double words in quad words
  Vmovdqu32("[$d]", xmm0);                                                      # Save
  PrintOutString($d, 16);
  Exit;
  ok assemble() =~ m(efghabcdmnopijkl)s;

Rs(@d)

Layout bytes in read only memory and return their label

   Parameter  Description
1  @d         Data to be laid out

Example:

  Start;
  Comment "Print a string from memory";
  my $s = "Hello World";

  my $m = Rs($s);  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

  Mov rsi, $m;
  PrintOutString rsi, length($s);
  Exit;
  ok assemble =~ m(Hello World);

Dbwdq($s, @d)

Layout data

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

Db(@bytes)

Layout bytes in the data segment and return their label

   Parameter  Description
1  @bytes     Bytes to layout

Dw(@words)

Layout words in the data segment and return their label

   Parameter  Description
1  @words     Words to layout

Dd(@dwords)

Layout double words in the data segment and return their label

   Parameter  Description
1  @dwords    Double words to layout

Dq(@qwords)

Layout quad words in the data segment and return their label

   Parameter  Description
1  @qwords    Quad words to layout

Rbwdq($s, @d)

Layout data

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

Rb(@bytes)

Layout bytes in the data segment and return their label

   Parameter  Description
1  @bytes     Bytes to layout

Rw(@words)

Layout words in the data segment and return their label

   Parameter  Description
1  @words     Words to layout

Rd(@dwords)

Layout double words in the data segment and return their label

   Parameter  Description
1  @dwords    Double words to layout

Rq(@qwords)

Layout quad words in the data segment and return their label

   Parameter  Description
1  @qwords    Quad words to layout

Comment(@comment)

Insert a comment into the assembly code

   Parameter  Description
1  @comment   Text of comment

Example:

  Start;

  Comment "Print a string from memory";  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

  my $s = "Hello World";
  my $m = Rs($s);
  Mov rsi, $m;
  PrintOutString rsi, length($s);
  Exit;
  ok assemble =~ m(Hello World);

Exit($c)

Exit with the specified return code or zero if no return code supplied

   Parameter  Description
1  $c         Return code

Example:

  Start;
  PrintOutString "Hello World";

  Exit;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

  ok assemble =~ m(Hello World);

SaveFirstFour()

Save the first 4 parameter registers

RestoreFirstFour()

Restore the first 4 parameter registers

RestoreFirstFourExceptRax()

Restore the first 4 parameter registers except rax so it can return its value

SaveFirstSeven()

Save the first 7 parameter registers

RestoreFirstSeven()

Restore the first 7 parameter registers

RestoreFirstSevenExceptRax()

Restore the first 7 parameter registers except rax which is being used to return the result

If($then, $else)

If

   Parameter  Description
1  $then      Then - required
2  $else      Else - optional

Example:

  Start;
  Mov rax, 0;
  Test rax,rax;

  If  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

   {PrintOutRegisterInHex rax;
   } sub
   {PrintOutRegisterInHex rbx;
   };
  Mov rax, 1;
  Test rax,rax;

  If  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

   {PrintOutRegisterInHex rcx;
   } sub
   {PrintOutRegisterInHex rdx;
   };
  Exit;
  ok assemble() =~ m(rbx.*rcx)s;

For($body, $register, $limit, $increment)

For

   Parameter   Description
1  $body       Body
2  $register   Register
3  $limit      Limit on loop
4  $increment  Increment

S($body, %options)

Create a sub with optional parameters name=> the name of the subroutine so it can be reused rather than regenerated, comment=> a comment describing the sub

   Parameter  Description
1  $body      Body
2  %options   Options.

registerSize($r)

Return the size of a register

   Parameter  Description
1  $r         Register

PushR(@r)

Push registers onto the stack

   Parameter  Description
1  @r         Register

PopR(@r)

Pop registers from the stack

   Parameter  Description
1  @r         Register

Example:

  Start;
  my $q = Rs(('a'..'p')x4);
  my $d = Ds('0'x128);
  Vmovdqu32(zmm0, "[$q]");
  Vprolq   (zmm0,   zmm0, 32);
  Vmovdqu32("[$d]", zmm0);
  PrintOutString($d, 64);
  Sub rsp, 64;
  Vmovdqu64 "[rsp]", zmm0;

  PopR rax;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

  PrintOutRaxInHex;
  Exit;
  ok assemble() =~ m(efghabcdmnopijklefghabcdmnopijklefghabcdmnopijklefghabcdmnopijkl)s;

PeekR($r)

Peek at register on stack

   Parameter  Description
1  $r         Register

PrintOutNl()

Write a new line

Example:

  Start;
  Comment "Print a string from memory";
  my $s = "Hello World";
  my $m = Rs($s);
  Mov rsi, $m;
  PrintOutString rsi, length($s);
  Exit;
  ok assemble =~ m(Hello World);

PrintOutString($string, $length)

One: Write a constant string to sysout. Two write the bytes addressed for the specified length to sysout

   Parameter  Description
1  $string    String
2  $length    Length

Example:

  Start;

  PrintOutString "Hello World";  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

  Exit;
  ok assemble =~ m(Hello World);

PrintOutRaxInHex()

Write the content of register rax to stderr in hexadecimal in big endian notation

Example:

  Start;
  my $q = Rs('abababab');
  Mov(rax, "[$q]");
  PrintOutString "rax: ";

  PrintOutRaxInHex;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

  PrintOutNl;
  Xor rax, rax;
  PrintOutString "rax: ";

  PrintOutRaxInHex;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

  PrintOutNl;
  Exit;
  ok assemble() =~ m(rax: 6261 6261 6261 6261.*rax: 0000 0000 0000 0000)s;

ClearRegisters(@registers)

Clear registers by setting them to zero

   Parameter   Description
1  @registers  Registers

ReverseBytesInRax()

Reverse the bytes in rax

PrintOutRaxInReverseInHex()

Write the content of register rax to stderr in hexadecimal in little endian notation

Example:

  Start;
  Mov rax, 0x88776655;
  Shl rax, 32;
  Or  rax, 0x44332211;
  PrintOutRaxInHex;

  PrintOutRaxInReverseInHex;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

  Exit;
  ok assemble() =~ m(8877 6655 4433 2211 1122 3344 5566 7788)s;

PrintOutRegisterInHex($r)

Print any register as a hex string

   Parameter  Description
1  $r         Name of the register to print

Example:

  Start;
  my $q = Rs(('a'..'p')x4);
  Mov r8,"[$q]";

  PrintOutRegisterInHex r8;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

  Exit;
  ok assemble() =~ m(r8: 6867 6665 6463 6261)s;

PrintOutRipInHex()

Print the instruction pointer in hex

PrintOutRflagsInHex()

Print the flags register in hex

PrintOutRegistersInHex()

Print the general purpose registers in hex

Example:

  Start;
  my $q = Rs('abababab');
  Mov(rax, 1);
  Mov(rbx, 2);
  Mov(rcx, 3);
  Mov(rdx, 4);
  Mov(r8,  5);
  Lea r9,  "[rax+rbx]";

  PrintOutRegistersInHex;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

  Exit;
  my $r = assemble();
  ok $r =~ m( r8: 0000 0000 0000 0005.* r9: 0000 0000 0000 0003.*rax: 0000 0000 0000 0001)s;
  ok $r =~ m(rbx: 0000 0000 0000 0002.*rcx: 0000 0000 0000 0003.*rdx: 0000 0000 0000 0004)s;

PrintOutMemoryInHex($addr, $length)

Print the specified number of bytes from the specified address in hex

   Parameter  Description
1  $addr      Address
2  $length    Length

allocateMemory($s)

Allocate memory via mmap

   Parameter  Description
1  $s         Amount of memory to allocate

Example:

  Start;
  my $N = 2048;
  my $n = Rq($N);
  my $q = Rs('a'..'p');

  allocateMemory "[$n]";  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

  PrintOutRegisterInHex rax;
  Vmovdqu8 xmm0, "[$q]";
  Vmovdqu8 "[rax]", xmm0;
  PrintOutString rax,16;
  PrintOutNl;

  Mov rbx, rax;
  freeMemory rbx, "[$n]";
  PrintOutRegisterInHex rax;
  Vmovdqu8 "[rbx]", xmm0;
  Exit;
  ok assemble() =~ m(abcdefghijklmnop)s;

  Start;
  my $N = 4096;
  my $S = registerSize rax;

  allocateMemory $N;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

  PrintOutRegistersInHex;
  Mov rbx, $N;
  PushR rbx;
  PushR rax;
  MemoryClear 0, $S;
  Mov rbx, $N-5;
  PrintOutString rax, rbx;
  PrintOutMemoryInHex rax, rbx;
  Exit;
  ok assemble() =~ m(abcdefghijklmnop)s;

freeMemory($a, $l)

Free memory via mmap

   Parameter  Description
1  $a         Address of memory to free
2  $l         Length of memory to free

Example:

  Start;
  my $N = 2048;
  my $n = Rq($N);
  my $q = Rs('a'..'p');
  allocateMemory "[$n]";
  PrintOutRegisterInHex rax;
  Vmovdqu8 xmm0, "[$q]";
  Vmovdqu8 "[rax]", xmm0;
  PrintOutString rax,16;
  PrintOutNl;

  Mov rbx, rax;

  freeMemory rbx, "[$n]";  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

  PrintOutRegisterInHex rax;
  Vmovdqu8 "[rbx]", xmm0;
  Exit;
  ok assemble() =~ m(abcdefghijklmnop)s;

  Start;
  my $N = 4096;
  my $S = registerSize rax;
  allocateMemory $N;
  PrintOutRegistersInHex;
  Mov rbx, $N;
  PushR rbx;
  PushR rax;
  MemoryClear 0, $S;
  Mov rbx, $N-5;
  PrintOutString rax, rbx;
  PrintOutMemoryInHex rax, rbx;
  Exit;
  ok assemble() =~ m(abcdefghijklmnop)s;

Fork()

Fork

Example:

  Start;                                                                        # Start the program

  Fork;                                                                         # Fork  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲


  Test rax,rax;
  If                                                                            # Parent
   {Mov rbx, rax;
    WaitPid;
    PrintOutRegisterInHex rax;
    PrintOutRegisterInHex rbx;
    GetPid;                                                                     # Pid of parent as seen in parent
    Mov rcx,rax;
    PrintOutRegisterInHex rcx;
   }
  sub                                                                           # Child
   {Mov r8,rax;
    PrintOutRegisterInHex r8;
    GetPid;                                                                     # Child pid as seen in child
    Mov r9,rax;
    PrintOutRegisterInHex r9;
    GetPPid;                                                                    # Parent pid as seen in child
    Mov r10,rax;
    PrintOutRegisterInHex r10;
   };

  Exit;                                                                         # Return to operating system

  my $r = assemble();

#    r8: 0000 0000 0000 0000   #1 Return from fork as seen by child
#    r9: 0000 0000 0003 0C63   #2 Pid of child
#   r10: 0000 0000 0003 0C60   #3 Pid of parent from child
#   rax: 0000 0000 0003 0C63   #4 Return from fork as seen by parent
#   rbx: 0000 0000 0003 0C63   #5 Wait for child pid result
#   rcx: 0000 0000 0003 0C60   #6 Pid of parent

  if ($r =~ m(r8:( 0000){4}.*r9:(.*)\s{5,}r10:(.*)\s{5,}rax:(.*)\s{5,}rbx:(.*)\s{5,}rcx:(.*)\s{2,})s)
   {ok $2 eq $4;
    ok $2 eq $5;
    ok $3 eq $6;
    ok $2 gt $6;
   }

  Start;                                                                        # Start the program
  GetUid;                                                                       # Userid
  PrintOutRegisterInHex rax;
  Exit;                                                                         # Return to operating system
  my $r = assemble();
  ok $r =~ m(rax:( 0000){3});

GetPid()

Get process identifier

Example:

  Start;                                                                        # Start the program
  Fork;                                                                         # Fork

  Test rax,rax;
  If                                                                            # Parent
   {Mov rbx, rax;
    WaitPid;
    PrintOutRegisterInHex rax;
    PrintOutRegisterInHex rbx;

    GetPid;                                                                     # Pid of parent as seen in parent  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    Mov rcx,rax;
    PrintOutRegisterInHex rcx;
   }
  sub                                                                           # Child
   {Mov r8,rax;
    PrintOutRegisterInHex r8;

    GetPid;                                                                     # Child pid as seen in child  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    Mov r9,rax;
    PrintOutRegisterInHex r9;
    GetPPid;                                                                    # Parent pid as seen in child
    Mov r10,rax;
    PrintOutRegisterInHex r10;
   };

  Exit;                                                                         # Return to operating system

  my $r = assemble();

#    r8: 0000 0000 0000 0000   #1 Return from fork as seen by child
#    r9: 0000 0000 0003 0C63   #2 Pid of child
#   r10: 0000 0000 0003 0C60   #3 Pid of parent from child
#   rax: 0000 0000 0003 0C63   #4 Return from fork as seen by parent
#   rbx: 0000 0000 0003 0C63   #5 Wait for child pid result
#   rcx: 0000 0000 0003 0C60   #6 Pid of parent

  if ($r =~ m(r8:( 0000){4}.*r9:(.*)\s{5,}r10:(.*)\s{5,}rax:(.*)\s{5,}rbx:(.*)\s{5,}rcx:(.*)\s{2,})s)
   {ok $2 eq $4;
    ok $2 eq $5;
    ok $3 eq $6;
    ok $2 gt $6;
   }

  Start;                                                                        # Start the program
  GetUid;                                                                       # Userid
  PrintOutRegisterInHex rax;
  Exit;                                                                         # Return to operating system
  my $r = assemble();
  ok $r =~ m(rax:( 0000){3});

GetPPid()

Get parent process identifier

Example:

  Start;                                                                        # Start the program
  Fork;                                                                         # Fork

  Test rax,rax;
  If                                                                            # Parent
   {Mov rbx, rax;
    WaitPid;
    PrintOutRegisterInHex rax;
    PrintOutRegisterInHex rbx;
    GetPid;                                                                     # Pid of parent as seen in parent
    Mov rcx,rax;
    PrintOutRegisterInHex rcx;
   }
  sub                                                                           # Child
   {Mov r8,rax;
    PrintOutRegisterInHex r8;
    GetPid;                                                                     # Child pid as seen in child
    Mov r9,rax;
    PrintOutRegisterInHex r9;

    GetPPid;                                                                    # Parent pid as seen in child  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    Mov r10,rax;
    PrintOutRegisterInHex r10;
   };

  Exit;                                                                         # Return to operating system

  my $r = assemble();

#    r8: 0000 0000 0000 0000   #1 Return from fork as seen by child
#    r9: 0000 0000 0003 0C63   #2 Pid of child
#   r10: 0000 0000 0003 0C60   #3 Pid of parent from child
#   rax: 0000 0000 0003 0C63   #4 Return from fork as seen by parent
#   rbx: 0000 0000 0003 0C63   #5 Wait for child pid result
#   rcx: 0000 0000 0003 0C60   #6 Pid of parent

  if ($r =~ m(r8:( 0000){4}.*r9:(.*)\s{5,}r10:(.*)\s{5,}rax:(.*)\s{5,}rbx:(.*)\s{5,}rcx:(.*)\s{2,})s)
   {ok $2 eq $4;
    ok $2 eq $5;
    ok $3 eq $6;
    ok $2 gt $6;
   }

  Start;                                                                        # Start the program
  GetUid;                                                                       # Userid
  PrintOutRegisterInHex rax;
  Exit;                                                                         # Return to operating system
  my $r = assemble();
  ok $r =~ m(rax:( 0000){3});

GetUid()

Get userid of current process

WaitPid()

Wait for the pid in rax to complete

Example:

  Start;                                                                        # Start the program
  Fork;                                                                         # Fork

  Test rax,rax;
  If                                                                            # Parent
   {Mov rbx, rax;

    WaitPid;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    PrintOutRegisterInHex rax;
    PrintOutRegisterInHex rbx;
    GetPid;                                                                     # Pid of parent as seen in parent
    Mov rcx,rax;
    PrintOutRegisterInHex rcx;
   }
  sub                                                                           # Child
   {Mov r8,rax;
    PrintOutRegisterInHex r8;
    GetPid;                                                                     # Child pid as seen in child
    Mov r9,rax;
    PrintOutRegisterInHex r9;
    GetPPid;                                                                    # Parent pid as seen in child
    Mov r10,rax;
    PrintOutRegisterInHex r10;
   };

  Exit;                                                                         # Return to operating system

  my $r = assemble();

#    r8: 0000 0000 0000 0000   #1 Return from fork as seen by child
#    r9: 0000 0000 0003 0C63   #2 Pid of child
#   r10: 0000 0000 0003 0C60   #3 Pid of parent from child
#   rax: 0000 0000 0003 0C63   #4 Return from fork as seen by parent
#   rbx: 0000 0000 0003 0C63   #5 Wait for child pid result
#   rcx: 0000 0000 0003 0C60   #6 Pid of parent

  if ($r =~ m(r8:( 0000){4}.*r9:(.*)\s{5,}r10:(.*)\s{5,}rax:(.*)\s{5,}rbx:(.*)\s{5,}rcx:(.*)\s{2,})s)
   {ok $2 eq $4;
    ok $2 eq $5;
    ok $3 eq $6;
    ok $2 gt $6;
   }

  Start;                                                                        # Start the program
  GetUid;                                                                       # Userid
  PrintOutRegisterInHex rax;
  Exit;                                                                         # Return to operating system
  my $r = assemble();
  ok $r =~ m(rax:( 0000){3});

readTimeStampCounter()

Read the time stamp counter

Example:

  Start;
  for(1..10)

   {readTimeStampCounter;  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

    PrintOutRegisterInHex rax;
   }
  Exit;
  my @s = split /
/, assemble();
  my @S = sort @s;
  is_deeply \@s, \@S;

OpenRead($file)

Open a file for read

   Parameter  Description
1  $file      File

Example:

  Start;                                                                        # Start the program
  my $f = Rs($0);                                                               # File to stat

  OpenRead($f);                                                                 # 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

Close($fdes)

Close a file descriptor

   Parameter  Description
1  $fdes      File descriptor

Example:

  Start;                                                                        # Start the program
  my $f = Rs($0);                                                               # File to stat
  OpenRead($f);                                                                 # 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

localData()

Map local data

LocalData::start($local)

Start a local data area on the stack

   Parameter  Description
1  $local     Local data descriptor

LocalData::free($local)

Free a local data area on the stack

   Parameter  Description
1  $local     Local data descriptor

LocalData::variable($local, $length, $comment)

Add a local variable

   Parameter  Description
1  $local     Local data descriptor
2  $length    Length of data
3  $comment   Optional comment

LocalVariable::stack($variable)

Address a local variable on the stack

   Parameter  Description
1  $variable  Variable

LocalData::allocate8($local, @comments)

Add some 8 byte local variables and return an array of variable definitions

   Parameter  Description
1  $local     Local data descriptor
2  @comments  Optional comment

MemoryClear($addr, $length)

Clear memory

   Parameter  Description
1  $addr      Stack offset of buffer address
2  $length    Stack offset of length of buffer

Read($fileDes, $addr, $length)

Read data the specified file descriptor into the specified buffer of specified length

   Parameter  Description
1  $fileDes   Stack offset of file descriptor
2  $addr      Stack offset of buffer address
3  $length    Stack offset of length of buffer

ReadFile($file, $addr, $length)

Read a file addressed by a local variable into memory writing the address and length of the memory into the specified local variables.

   Parameter  Description
1  $file      Address of file name in a local variable
2  $addr      Local variable for address of memory
3  $length    Local variable for length of file

StatSize($file)

Stat a file to get its size in rax

   Parameter  Description
1  $file      File

Example:

  Start;                                                                        # Start the program
  my $f = Rs($0);                                                               # File to stat

  StatSize($f);                                                                 # 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));
   }

assemble(%options)

Assemble the generated code

   Parameter  Description
1  %options   Options

Example:

  Start;
  PrintOutString "Hello World";
  Exit;

  ok assemble =~ m(Hello World);  # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲

Private Methods

label()

Create a unique label

Index

1 allocateMemory - Allocate memory via mmap

2 assemble - Assemble the generated code

3 ClearRegisters - Clear registers by setting them to zero

4 Close - Close a file descriptor

5 Comment - Insert a comment into the assembly code

6 Db - Layout bytes in the data segment and return their label

7 Dbwdq - Layout data

8 Dd - Layout double words in the data segment and return their label

9 Dq - Layout quad words in the data segment and return their label

10 Ds - Layout bytes in memory and return their label

11 Dw - Layout words in the data segment and return their label

12 Exit - Exit with the specified return code or zero if no return code supplied

13 For - For

14 Fork - Fork

15 freeMemory - Free memory via mmap

16 GetPid - Get process identifier

17 GetPPid - Get parent process identifier

18 GetUid - Get userid of current process

19 If - If

20 label - Create a unique label

21 localData - Map local data

22 LocalData::allocate8 - Add some 8 byte local variables and return an array of variable definitions

23 LocalData::free - Free a local data area on the stack

24 LocalData::start - Start a local data area on the stack

25 LocalData::variable - Add a local variable

26 LocalVariable::stack - Address a local variable on the stack

27 MemoryClear - Clear memory

28 OpenRead - Open a file for read

29 PeekR - Peek at register on stack

30 PopR - Pop registers from the stack

31 PrintOutMemoryInHex - Print the specified number of bytes from the specified address in hex

32 PrintOutNl - Write a new line

33 PrintOutRaxInHex - Write the content of register rax to stderr in hexadecimal in big endian notation

34 PrintOutRaxInReverseInHex - Write the content of register rax to stderr in hexadecimal in little endian notation

35 PrintOutRegisterInHex - Print any register as a hex string

36 PrintOutRegistersInHex - Print the general purpose registers in hex

37 PrintOutRflagsInHex - Print the flags register in hex

38 PrintOutRipInHex - Print the instruction pointer in hex

39 PrintOutString - One: Write a constant string to sysout.

40 PushR - Push registers onto the stack

41 Rb - Layout bytes in the data segment and return their label

42 Rbwdq - Layout data

43 Rd - Layout double words in the data segment and return their label

44 Read - Read data the specified file descriptor into the specified buffer of specified length

45 ReadFile - Read a file addressed by a local variable into memory writing the address and length of the memory into the specified local variables.

46 readTimeStampCounter - Read the time stamp counter

47 registerSize - Return the size of a register

48 RestoreFirstFour - Restore the first 4 parameter registers

49 RestoreFirstFourExceptRax - Restore the first 4 parameter registers except rax so it can return its value

50 RestoreFirstSeven - Restore the first 7 parameter registers

51 RestoreFirstSevenExceptRax - Restore the first 7 parameter registers except rax which is being used to return the result

52 ReverseBytesInRax - Reverse the bytes in rax

53 Rq - Layout quad words in the data segment and return their label

54 Rs - Layout bytes in read only memory and return their label

55 Rw - Layout words in the data segment and return their label

56 S - Create a sub with optional parameters name=> the name of the subroutine so it can be reused rather than regenerated, comment=> a comment describing the sub

57 SaveFirstFour - Save the first 4 parameter registers

58 SaveFirstSeven - Save the first 7 parameter registers

59 SetLabel - Set a label in the code section

60 Start - Initialize the assembler

61 StatSize - Stat a file to get its size in rax

62 WaitPid - Wait for the pid in rax to complete

Installation

This module is written in 100% Pure Perl and, thus, it is easy to read, comprehend, use, modify and install via cpan:

sudo cpan install Nasm::X86

Author

philiprbrenan@gmail.com

http://www.appaapps.com

Copyright

Copyright (c) 2016-2021 Philip R Brenan.

This module is free software. It may be used, redistributed and/or modified under the same terms as Perl itself.