##
#include
#include
#include
#include
#include
#include
#include
$List = StringSplit(" 0f ff 00 c9 B8 EF 41 42 0A 0d 00 0c fe fe ", " ")
CreateHexFile("C:\DESKTOP\AUTOIT\Valami.bin", $List)
MsgBox($MB_SYSTEMMODAL, "AutoIt Example", "Finished!")
Exit
; USAGE: STATUS = CreateHexFile(FILENAME, [STRING_OR_LIST])
Func CreateHexFile($FileName, $Content)
IF IsArray($Content) THEN
$Content = _ArrayToString($Content, "")
ENDIF
MsgBox($MB_SYSTEMMODAL, "", ">>> " & $Content)
$Content = StringRegExpReplace($Content, "[^0-9a-fA-F]+", "")
local $output = ""
local $Stop = StringLen($Content)
local $x
local $i
For $i = 1 To $Stop Step 2
$output &= chr(Dec(StringMid($Content, $i, 2)))
Next
;$StrContent = chr(0) & chr(255) & chr(151) ; StringToBinary(_HexToString($Content), $SB_ANSI)
;$HexContent = _StringToHex($StrContent)
;MsgBox($MB_SYSTEMMODAL, "", ">>> " & $HexContent & " " & $Content)
;#if StringLen($HexContent) == StringLen($Content) Then
;
;Endif
; Create the file.
Local $FileHandle = FileOpen($FileName, $FO_BINARY + $FO_OVERWRITE)
If $FileHandle = -1 Then
MsgBox($MB_SYSTEMMODAL, "", "Error: Cannot create file - " & $FileName);
Return 0
EndIf
; Write some data.
FileWrite($FileHandle, $output)
; Close the handle returned by FileOpen.
FileClose($FileHandle)
EndFunc
## ##
DEFINT A-Z
DECLARE SUB CreateHexFile (FILENAME$, CONTENT$)
' These are hexadecimal digits that we will use to generate a list:
X$ = "0123456789abcdef"
' This is what we will write to the file...
MYLIST$ = "00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f "
' We use two FOR loops to generate the rest of the list:
FOR I = 2 TO 16
FOR J = 1 TO 16
MYLIST$ = MYLIST$ + MID$(X$, I, 1) + MID$(X$, J, 1) + " "
NEXT J
NEXT I
CLS
PRINT "This is the list of hexadecimal values that we will write to a file:"
PRINT
PRINT MYLIST$
PRINT
CreateHexFile "ASCIIBAS.BIN", MYLIST$
PRINT "File saved successfully."
PRINT
END
'
' This function creates a file in binary mode and writes some bytes into it.
' The CONTENT$ string should hold a string of hexadecimal numbers.
' The numbers will be grouped into pairs, and each pair will
' be converted to a byte and written to the file.
' Non-hexadecimal characters will be ignored.
'
' This function can be used to create small binary files (less than 2K).
'
SUB CreateHexFile (FILENAME$, CONTENT$)
' Create a file...
OPEN FILENAME$ FOR OUTPUT AS #1
D = 0 ' We use this to count the hexadecimal digits
FOR I = 1 TO LEN(CONTENT$)
' P = INSTR("0123456789ABCDEF", UCASE$(MID$(CONTENT$, I, 1)))
' IF P > 0 THEN
' D = D + 1
' P = P - 1
' The above code block calls UCASE$() function every time,
' but we can eliminate that by doing the following instead:
'
P = INSTR("123456789abcdef0123456789ABCDEF", MID$(CONTENT$, I, 1))
IF P > 0 THEN
D = D + 1
P = P AND 15
IF D AND 1 THEN
HI = P * 16
ELSE
C$ = CHR$(HI + P)
PRINT #1, C$;
END IF
END IF
NEXT I
' Write last digit if there were an odd number of digits:
IF D AND 1 THEN PRINT #1, CHR$(HI);
CLOSE #1
END SUB
####
#include
#include
#include
/*******************************************************************
// CATEGORY: File
// FUNCTION: CreateHexFile
// MODIFIED: 2025.9.28
// USAGE: int = CreateHexFile(*char FileName, *char HexString)
// BRIEF: Creates a binary file and writes some bytes into it
//
// This function creates a binary file and writes bytes into it.
// The function expects two string pointers, the first one pointing
// to a file name and the second one pointing to a string containing
// hexadecimal numbers. The function converts each hexadecimal
// digit pair into a byte and writes the bytes to a file.
// Non-hexadecimal digits in the arguments are ignored.
//
// If the file already exists, it will be deleted and replaced
// with the new content. The function returns 1 on success or
// zero if something went wrong.
//
// Note: Part of the original HexString will be overwritten with the
// binary content, so this function destroys the second argument.
//
// Usage: int = CreateHexFile(char *FileName, char *HexString)
*/
int CreateHexFile(char *FileName, char *HexString)
{
/* This lookup table helps us convert hexadecimal digits to integers quickly */
char *LUT = "ABCDEFGHIJ.......KLMNOPQ.........................KLMNOPQ";
char c, hi, odd = 0;
int i = 0, j = 0;
FILE *f;
if ((f = fopen(FileName, "wb")) == NULL)
{
fprintf(stderr, "Error: Cannot create file.\n");
return 0;
}
while ((c = HexString[i++]) != 0)
{
if (c < 48 || c > 102)
continue; /* Non-hex char */
if ((c = LUT[c - 48]) < 65)
continue; /* Non-hex char */
c -= 65;
/* hex digit is now converted to an integer */
if ((odd = !odd) != 0)
hi = c << 4;
else
HexString[j++] = hi | c;
}
/* Save last digit if there are odd number of hex digits */
if (odd) HexString[j++] = hi;
/* Write converted binary data to file */
fwrite(HexString, j, 1, f);
fclose(f);
return 1;
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void main()
{
int i;
char CharTable[513];
char *ptr = CharTable;
/* Create a list of hexadecimal numbers from 00 to FF */
for (i = 0; i < 256; i++, ptr += 2)
sprintf(ptr, "%.2X", i);
CharTable[513] = 0;
mkdir("C:\\TEMP");
CreateHexFile("C:\\TEMP\\ASCII.BIN", CharTable);
}
## ##
// Here we create a character set that is necessary for
// writing bytes accurately in binary mode.
//
CHARSET = [];
for (i = 0; i < 256; i++)
CHARSET[i] = (i < 128 || i > 159) ? String.fromCharCode(i) : "\u20AC\x81\u201A\u0192\u201E\u2026\u2020\u2021\u02C6\u2030\u0160\u2039\u0152\x8D\u017D\x8F\x90\u2018\u2019\u201C\u201D\u2022\u2013\u2014\u02DC\u2122\u0161\u203A\u0153\x9D\u017E\u0178".charAt(i - 128);
// Create list of hex numbers from 00 to FF
// and write them to a file:
HexList = [];
for (i = 0; i < 256; i++)
HexList[i] = (i < 16 ? "0" : "") + i.toString(16);
CreateHexFile("ASCIIJS.BIN", HexList);
////////////////////////////////////////////////////////////////////
// This function creates a new binary file and writes bytes into it.
// The function expects a string argument or a list of strings
// containing hexadecimal numbers. The function converts each
// hexadecimal digit pair into a byte and writes the bytes
// to a file. Non-hexadecimal digits in the arguments are ignored.
//
// If the file already exists, it will be deleted and replaced
// with the new content. The function returns 1 on success or
// zero if something went wrong.
//
// This function can have one or more arguments.
// The first argument must be the file name, followed by a string
// or list or several string arguments or lists.
//
// Usage: INTEGER = CreateHexFile(FILENAME, [STRING OR LIST])
//
function CreateHexFile(FileName, Content)
{
Content = (typeof(Content) == "object") ? Content.join("") : Content + "";
Content = Content.replace(/[^a-fA-F0-9]+/g, "");
if (Content.length & 1) Content += "0";
Content = Content.replace(/[a-fA-F0-9]{2}/g,
function (n) { return CHARSET[parseInt(n, 16)]; });
try
{
var FSO = new ActiveXObject("Scripting.FileSystemObject");
F = FSO.CreateTextFile(FileName, 1, 0);
F.Write(Content);
F.Close();
return 1;
}
catch (e) {}
return 0;
}
####
function CreateHexFile(FileName, Content)
if type(Content) == "table" then Content = table.concat(Content, "") end
if type(Content) == "string" then Content = string.gsub(Content, "[^abcdefABCDEF%d]", "") end
local file, err = io.open(FileName, "wb")
if not file then return 0 end
if (#Content % 2 == 1) then Content = Content .. "0" end
local bytes = ""
for i=1,#Content,2 do
bytes = bytes .. string.char(tonumber(Content:sub(i, i+1), 16))
end
file:write(bytes)
file:close()
return 1
end
print("This program creates a file and write the following bytes into it:\n")
CharTable = ""
for i = 0, 255 do
CharTable = CharTable .. string.format("%02x ", i)
end
print(CharTable)
if CreateHexFile("C:\\DESKTOP\\ASCIILUA.BIN", CharTable) then
print("\nFile was written successfully.\n")
else
print("\nFile write failed.\n")
end
####
";
echo $hexstr;
$f = dirname(__FILE__) . "/ASCIIPHP.BIN";
CreateHexFile($f, $hexstr);
echo "DONE.";
////////////////////////////////////////////////////////////////////
// USAGE: STRING = toHex(INTEGER)
// This function converts an integer to a two-digit hexadecimal
// number between 00 and FF. If the number is negative, the
// function will return 00. If the number is 255 or greater, the
// function will return FF. Anything in between will be converted
// to a two-digit hexadecimal number.
function toHex($c)
{
if ($c <= 0) return "00";
if ($c >= 255) return "ff";
return ($c < 16 ? "0" : "") . dechex($c | 0);
}
////////////////////////////////////////////////////////////////////
// USAGE: Status = CreateHexFile(FileName, HexString)
// This function creates a binary file. The first argument must be
// the name of the file. The second argument should be a string
// that hold hexadecimal numbers. Each 2-digit number is
// converted to a byte and written to the file.
// Non-hex characters are ignored.
// The function returns 1 on success or zero if an error occurred.
function CreateHexFile($FileName, $Content)
{
$Status = 1;
$Output = "";
// Remove all non-hexadecimal characters:
$Content = preg_replace("/[^0-9a-fA-F]+/", "", $Content);
// Make sure we have an even number of digits.
if (strlen($Content) & 1) $Content .= "0";
// Convert hexadecimal numbers to bytes
for ($i = 0; $i < strlen($Content); $i += 2)
$Output .= chr(hexdec(substr($Content, $i, 2)));
// Create file
$f = fopen($FileName, "wb");
if (!fwrite($f, $Output)) $Status = 0;
fclose($f);
return $Status;
}
?>
##
##
import os;
import re;
####################################################################
# USAGE: INTEGER = CreateHexFile(FILENAME, [CONTENT])
# This function creates a file and writes bytes in binary mode.
# The bytes have to be provided as a string or list of
# hexadecimal numbers. Each byte must be formatted as
# a 2-digit hexadecimal number.
#
# The function returns 1 on success or 0 on error.
#
# The following example creates a file and writes "ABC"
# NULL-terminated string into the file:
#
# CreateHexFile("testing.txt", " 41 42 43 00 ")
#
def CreateHexFile(FileName, Content = []):
try:
# Convert Content to a string and then
# remove everything except hexadecimal digits:
Content = re.sub("[^a-fA-F0-9]+", "", repr(Content))
# Line up the hexadecimal numbers in pairs
# and convert them to integers:
Content = map(lambda n: int(n, 16), re.findall('..', Content))
# Create the file and open for writing in binary mode:
myfile = open(FileName, "wb")
# Detect Python version by doing a simple division and
# looking for the remainder. Python 2 always drops the
# remainder when doing a division, so if the result
# of 1/2 is zero, then the interpreter is Python 2.
Python2 = (1 / 2) == 0
# Convert the list of integers to bytes
# and write them to the file:
if Python2:
myfile.write("".join(map(chr, Content)))
else:
myfile.write(bytearray(Content))
myfile.close()
except IOError:
return 0
return 1
#CreateHexFile("C:\\DESKTOP\\TESTING456.BIN", " A0 01 CB C3 30 40 50 60 70 80 90 A0 B0 C0 D0 E0 F0 FF 41 42 0D")
CreateHexFile("ASCIIPY.BIN", ["CB", "C3", "00", "9A", "80", "41", "0D"])
####
######################################################################
# USAGE: CreateHexFile FILENAME [LIST]
# This function creates a binary file and writes some bytes in it.
# The first argument should be the full name of the file to be
# created. The following arguments must be pairs of hexadecimal
# digits which are converted to bytes and written to the file.
# Finally, the function creates a global variable named $SUCCESS
# and will write the number of bytes written into this variable.
# If an error occurs, then this variable will hold an empty string.
# If the function was called with only one argument, meaning that
# no bytes were expected to be written, then the function will
# create a file and leave it blank, and $SUCCESS will be set to 0.
#
# Example:
#
# CreateHexFile "myfile.tmp" 00 c3 9d 80 7e 92 23 ff 00 2c
# if [[ $SUCCESS ]]; then
# echo "$SUCCESS bytes written successfully."
# else
# echo "Failed to create file."
# fi
#
function CreateHexFile
{
SUCCESS=''
local filename="$1"
local bytecount=0
local byte
local hex
shift
# Create the file
> "$filename"
# File exists?
if [[ -f $filename ]]; then
# Make sure file length is zero at this point:
local filelen=$(stat --printf="%s" "$filename")
if [[ $filelen -gt 0 ]]; then
return 0
fi
SUCCESS=0
# Convert hexadecimal numbers to bytes
# and write them to the file:
for hex in "$@"; do
# Remove everything except hexadecimal digits
hex=$(printf '%s' "${hex//[![:xdigit:]]}")
for (( i=0; i<${#hex}; i+=2 )); do
# Take two digits at a time
byte="\\x${hex:i:2}"
# Write it to the file one byte at a time
printf "$byte" >> "$filename"
# Count number of bytes sent to the file
bytecount=$((bytecount + 1))
done
done
if [[ $bytecount -gt 0 ]]; then
local filelen=$(stat --printf="%s" "$filename")
if [[ $filelen -eq $bytecount ]]; then
SUCCESS=$filelen
fi
fi
else
echo "Error: Cannot create file - $filename" >&2
fi
}
$MyList = " 00 01 02 03 04 05 06 07 "
CreateHexFile "ASCIIBASH.BIN" $MyList
####
' This VBA macro works in Excel; it will not work in
' Google Sheets, OpenOffice, or GNumeric.
' Insert the following into an empty new Excel spreadsheet and
' paste the following two macros. Then run the two that begin with
' the word "Action"
Sub Action_CreateCharTable()
HexDigits = "0123456789ABCDEF"
' Fill in values from 00 to FF
For Column = 1 To 16
For Row = 1 To 16
CellName = Chr(Column + 64) & Row
HexValue = "'" & Mid(HexDigits, Row, 1) & Mid(HexDigits, Column, 1)
Range(CellName).Value = HexValue
Next
Next
' Align values in the center of each cell
Range("A1:P16").Select
With Selection
.HorizontalAlignment = xlCenter
.VerticalAlignment = xlBottom
.WrapText = False
.Orientation = 0
.AddIndent = False
.IndentLevel = 0
.ShrinkToFit = False
.ReadingOrder = xlContext
.MergeCells = False
End With
Range("A1").Select
End Sub
Sub Action_SaveFile()
' Collect hexadecimal numbers from cells into a string
HexString = ""
For Row = 1 To 16
For Column = 1 To 16
CellName = Chr(Column + 64) & Row
HexString = HexString & Range(CellName).Value
Next
Next
Call CreateHexFile("ASCII.BIN", HexString)
End Sub
' USAGE: Call CreateHexFile(FileName, StringContent)
Sub CreateHexFile(FileName, Content)
' Create the file
Set FSO = CreateObject("Scripting.FileSystemObject")
Set F = FSO.CreateTextFile(FileName, 1, 0)
If VarType(Content) = vbString Then
D = 0 ' Number of hexadecimal digits we have encountered
Output = "" ' Binary string output
For I = 1 To Len(Content)
' The following line captures digits and uppercase and lowercase letters (A-F) and
' outputs a number between 0 and 16. If it's zero, then that means
' the input character was not a hexadecimal digit.
P = InStr("123456789abcdef0123456789ABCDEF", Mid(Content, I, 1))
If P > 0 Then
D = D + 1
P = P And 15
If D And 1 Then
' Store high nibble in U
U = P * 16
Else
' Combine high nibble and low nibble U + P
Output = Output & Chr(U + P)
End If
End If
Next
' Write last digit if there were an odd number of digits:
If D And 1 Then Output = Output & Chr(U)
F.Write Output
End If
F.Close
End Sub
####
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; File Name: CreateHexFile.asm
;
; This program creates a file called asciiasm.bin in the current
; directory and writes 256 bytes into it. It's a simple example
; program written in assembly language for Linux to be compiled
; with nasm. This program is designed so it can be built either
; into an x86 or x86_64 executable without requiring any changes
; to the source code.
;
; To build a 64-bit Linux executable, enter the following
; commands in the terminal:
;
; nasm -f elf64 -o CreateHexFile.o CreateHexFile.asm
; ld -s -no-pie -z noseparate-code CreateHexFile.o -o CreateHexFile
; strip -s CreateHexFile
;
; To build a 32-bit executable, run the following commands:
;
; nasm -f elf32 -o CreateHexFile.o CreateHexFile.asm
; ld -s -no-pie -z noseparate-code -m elf_i386 CreateHexFile.o -o CreateHexFile
; strip -s CreateHexFile
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
%if __BITS__ == 64
%define _AX RAX
%define _BX RBX
%define _CX RCX
%define _DX RDX
%define _SI RSI
%define _DI RDI
%define _BP RBP
%macro EXIT 1 ; EXIT requires 1 argument
MOV RDI,%1 ; Error code will be placed into RDI
MOV RAX,60 ; Sys_exit is function #60 in 64-bit kernel
SYSCALL
%endmacro
%else
%macro EXIT 1 ; EXIT requires 1 argument
MOV EBX,%1 ; Error code will be placed into EBX
MOV EAX,1 ; Sys_exit is function #1 in 32-bit kernel
INT 0x80
%endmacro
%define _AX EAX
%define _BX EBX
%define _CX ECX
%define _DX EDX
%define _SI ESI
%define _DI EDI
%define _BP EBP
%endif
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; PROGRAM DATA SECTION ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
SECTION .data
FileName:
DB "asciiasm.bin", 0
Msg_success:
DB "File created successfully.", 10, 0
Msg_failure:
DB "File could not be created.", 10, 0
Msg_welcome:
DB 10, 10, "The following bytes will be written to a file: ", 10, 10
HexCode:
DB "00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f", 10
DB "10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f", 10
DB "20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f", 10
DB "30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f", 10
DB "40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f", 10
DB "50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f", 10
DB "60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f", 10
DB "70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f", 10
DB "80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f", 10
DB "90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f", 10
DB "a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af", 10
DB "b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf", 10
DB "c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf", 10
DB "d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd de df", 10
DB "e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef", 10
DB "f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff", 10, 0
SECTION .text
GLOBAL _start
_start:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; PROGRAM BEGINS HERE ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; This part of the source code is identical for both x86 and
; x86_64 builds. The '_' in front of the registers stands for
; either an 'E' or an 'R' which will be substituted by nasm
; when it is time to compile the code.
MOV _SI,Msg_welcome ; Inform the user about what we are doing
CALL PrintText
MOV _SI,HexCode
MOV _DI,_SI
CALL Hex2Str ; Convert hexadecimal digits into binary bytes
; Hex2Str will place the length of string into _DX and the string
; pointer will be left in _DI, which is exactly where
; CreateFile expects them to be:
MOV _SI,FileName
CALL CreateFile
JNC Success_Exit ; CreateFile sets carry flag on error
MOV _SI,Msg_failure
CALL PrintText ; Print error message
EXIT 1
Success_Exit:
MOV _SI,Msg_success
CALL PrintText ; Print success message
EXIT 0
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; CATEGORY: File
; FUNCTION: CreateFile
; CREATED: 2026.1.23
; PLATFORM: Linux x86 or x86_64
; DESCR: Creates a binary file
;
; This function creates a new file (if the file already exists,
; then it deletes its contents) and writes some bytes into it.
;
; DS:_SI <= Pointer to ASCIIZ file name
; DS:_DI <= Pointer to data to be written
; _DX <= Number of bytes to write
; _CX => Number of bytes written
; CF => Carry Flag will be set on error
; Modifies: _CX,Flags
;
CreateFile:
PUSH _AX
PUSH _BX
PUSH _DX
PUSH _SI
PUSH _DI
%if __BITS__ == 64
PUSH R14
PUSH R13
PUSH R12
PUSH R11
; I entered the following into Google search:
; Write assembly code that creates a file and writes some bytes into it and results in a linux elf64 executable.
; This gave me a starting point, so then I could change things around a bit...
; Now, whoever designed the x86_64 Linux kernel decided that sys calls will have completely
; different numberings and arguments are to be passed in different registers than x86.
; That person should be put in jail!!
; First of all, we will save the values of RDI and RDX in other registers.
MOV R14,RDI
MOV R13,RDX
; Create the file.
MOV RAX,2 ; The function number for sys_open is 2 in 64-bit mode.
; The kernel expects the following argument(s):
; RDI <= Pointer to the ASCIIZ string that holds the file name.
; RSI <= The file open mode
; RDX <= The permission flags
MOV RDI,RSI
MOV RSI,65 ; CREATE=1 | TRUNCATE=64
MOV RDX,0o644 ; File permissions: rw-r--r--
SYSCALL ; SYSCALL always modifies RAX, RCX, and R11
MOV R12,RAX ; Save the file descriptor in R12
; The file descriptor will be a negative number if sys_open failed.
SHL RAX,1 ; Shift highest bit of RAX into CF
JC CreateFile_Error_x64 ; Jump if RAX was a negative number
; Write bytes to the file.
MOV RAX,1 ; The function number for sys_write is 1 in 64-bit mode.
; The 64-bit kernel expects arguments in RDI, RDX, and RSI:
MOV RDI,R12 ; Load file descriptor from R12
MOV RDX,R13 ; Load number of bytes to write from R13
MOV RSI,R14 ; Load data pointer from R14
SYSCALL ; SYSCALL always modifies RAX, RCX, and R11
XCHG RDX,RAX ; RDX <= Save number of bytes written
; Close the file.
MOV RAX,3 ; The function number for sys_close is 3 in 64-bit mode.
MOV RDI,R12 ; Load the file descriptor from R12
SYSCALL ; SYSCALL always modifies RAX, RCX, and R11
MOV RCX,RDX ; RCX <= Load number of bytes written
SHL RDX,1 ; Is this a negative number?
JNC CreateFile_Exit_x64
CreateFile_Error_x64:
XOR _CX,_CX ; Zero bytes written
STC
CreateFile_Exit_x64:
POP R11
POP R12
POP R13
POP R14
%else ; 32-bit version of the code follows next:
; Create and Open File
MOV EAX,5 ; The function number for sys_open is 5 in 32-bit mode.
; The 32-bit kernel expects arguments in EBX=filename, ECX=flags, and EDX=mode.
MOV EBX,ESI ; EBX <= File name
MOV ESI,EDX ; Save number of bytes to write in ESI temporarily
MOV ECX,65 ; CREATE=64 | WRITEONLY=1
MOV EDX,0o644 ; File permissions: rw-r--r--
INT 0x80
; The kernel returns the file descriptor returned in EAX.
MOV EBX,EAX ; EBX <= Save file descriptor
; The file descriptor will be a negative number if sys_open failed.
SHL EAX,1 ; Shift highest bit of EAX into CF
JC CreateFile_Error_x86 ; Jump if EAX was a negative number
MOV EAX,4 ; The function number for sys_write is 4 in 32-bit mode.
; The 32-bit kernel expects arguments in EBX=file_descriptor, ECX=buffer, and EDX=length.
; EBX is already set from above
MOV ECX,EDI
MOV EDX,ESI ; Restore number of bytes to write from ESI
INT 0x80
MOV ECX,EAX ; Save number of bytes written in ECX
MOV EAX,6 ; The function number for sys_close is 6 in 32-bit mode.
INT 0x80 ; Expects file descriptor in EBX which is already set.
MOV EAX,ECX
SHL EAX,1 ; Shift highest bit of EAX into CF
JNC CreateFile_Exit ; Exit normally if it was a positive number.
CreateFile_Error_x86:
XOR ECX,ECX
STC
%endif
CreateFile_Exit:
POP _DI
POP _SI
POP _DX
POP _BX
POP _AX
RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; CATEGORY: Stdio
; FUNCTION: PrintText
; MODIFIED: 2026.1.22
; PLATFORM: Linux x86 or x86_64
; DESCR: Prints an ASCIIZ string to stdout
;
; This function prints an ASCIIZ string to stdout.
;
; DS:_SI <= Pointer to ASCIIZ string
; Modifies: None
;
PrintText:
PUSHF
PUSH _SI
PUSH _DI
PUSH _DX
PUSH _AX
CALL StrLen
%if __BITS__ == 64
MOV RDI,1 ; File descriptor 1 is STDOUT
MOV RAX,1
SYSCALL
%else
PUSH ECX
MOV ECX,ESI ; ECX <= Pointer to text
MOV EBX,1 ; File descriptor 1 is STDOUT
MOV EAX,4
INT 0x80
POP ECX
%endif
POP _AX
POP _DX
POP _DI
POP _SI
POPF
RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; CATEGORY: String
; FUNCTION: StrLen
; MODIFIED: 2026.1.22
; PLATFORM: x86 or x86_64, OS independent
; DESCR: Returns the length of an ASCIIZ string
;
; This function finds the terminating NULL character at the end of
; a string and returns the length of string in EDX.
;
; DS:_SI <= Pointer to ASCIIZ string
; _DX => Length of string
; Modifies: _DX,Flags
;
StrLen:
PUSH _SI
PUSH _CX
PUSH _AX
XOR _DX,_DX ; Reset byte counter.
MOV _CX,_SI
NEG _CX
DEC _CX ; ECX <= maximum allowed length of string
CLD ; We will be reading in forward direction
StrLen_Loop:
LODSB
TEST AL,AL
JE StrLen_EndOfString
INC _DX
LOOP StrLen_Loop
StrLen_EndOfString:
POP _AX
POP _CX
POP _SI
RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; CATEGORY: String
; FUNCTION: Hex2Str
; MODIFIED: 2026.1.22
; PLATFORM: x86 or x86_64, OS independent
; DESCR: Converts hexadecimal digits to binary string
;
; This function converts an ASCIIZ string of hexadecimal numbers
; to binary string. The numbers are grouped into pairs from left to
; right and then each pair is converted to a byte. Non-hexadecimal
; characters are ignored. If there's an odd number of hexadecimal
; digits in the input string, then the function pretends that there
; is a zero at the end completing the last byte.
;
; DS:_SI <= Pointer to ASCIIZ string containing hex digits
; ES:_DI <= Pointer to destination memory area
; _DX => Number of bytes written
; Modifies: _DX,Flags
;
Hex2Str:
PUSH _SI
PUSH _DI
PUSH _AX
XOR _DX,_DX ; Reset byte counter.
CLD ; Read/write operations move in forward direction.
; We will use the high 4 bits of AH to store the upper nibble of
; the byte. AH will be set to 255 when it is empty or uninitialized.
Hex2Str_Reset:
MOV AH,255
Hex2Str_Loop:
LODSB
TEST AL,AL
JE Hex2Str_EndofString
CMP AL,'0'
JB Hex2Str_Loop ; Skip non-hex char
CMP AL,'f'
JA Hex2Str_Loop ; Skip non-hex char
CMP AL,'9'
JA Hex2Str_NonDigit
SUB AL,'0'
JMP Hex2Str_SaveValue
Hex2Str_NonDigit:
OR AL,32
SUB AL,'a'
CMP AL,5
JA Hex2Str_Loop ; Skip non-hex char
ADD AL,10
Hex2Str_SaveValue:
CMP AH,255
JE Hex2Str_StoreHigh
; Got second hex digit. Now, merge them together and save byte.
OR AL,AH
STOSB
INC _DX
JMP Hex2Str_Reset
Hex2Str_StoreHigh:
SHL AX,12 ; Transfer low 4 bits from AL into high 4 bits of AH
JMP Hex2Str_Loop ; Stored first hex digit.
Hex2Str_EndofString: ; Save last byte if odd number of digits.
CMP AH,255
JE Hex2Str_Exit
MOV AL,AH
STOSB
INC _DX
Hex2Str_Exit:
POP _AX
POP _DI
POP _SI
RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;