NASM - The Netwide Assembler

NASM Forum => Example Code => Topic started by: eberdeed on October 22, 2010, 04:21:35 PM

Title: Revamped 64 bit Code.
Post by: eberdeed on October 22, 2010, 04:21:35 PM
Here is the code with code blocks.
I prettied it up a bit.

Ed Eberle
Code: [Select]

; Edward C. Eberle
; San Diego, California  USA
; eberdeed@pacbell.net
; Language nasm (the Netwide Assembler)
; Created on a 64 bit Debian Linux System.
; Distributed under the GNU License.
; Welcome to 64 bit registries and stuff.
; This program echos back what is written at the
; command line.  It also produces a text file
; that is a copy of what was writen during
; the session.
; The rules:
; 1.  All offsets from a memory location (read label)
; require a 32 bit register (begins with an e eax, ebx...)
; 2.  All characters get a quadword for storage.
;   True because the Linux used accepts UTF-8 encoding.


BITS 64 ; Default to 64 bit alignment
; Also requires quadword.
GLOBAL main ; Program entry point
extern fgets ; C routines used to do the input and output.
extern fgetc
extern fopen
extern fputc
extern putchar
extern fputs
extern puts
extern getc
extern getchar
extern fclose
extern clearerr

;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
; Data Storage (Variables)
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

SECTION .bss
txtstorage: resq 0xFFFF
message: resq 0x100
varfilename: resq 0x100
varlenfilename: resq    0x01
varfilepointer: resq 0x01
docsize: resq 0x01
varfileaccess: resq 0x04
strlen: resq 0x01
tmpchr: resq 0x01
offset: resq 0x01
countr: resd 0x01

;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
; Fixed Data (Strings)
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

SECTION .data

fileerrorstr: dq "The program has had an Input -- Output error.",0x00
lenfileerrorstr: dd   $-fileerrorstr
fatalerror: dq "The program has made a fatal error.  END PROGRAM.",0x00
lenfatalerror: dd $-fatalerror
samplestr: dq "A good day!",0x00 ;The day.
lensamplestr:   dd $-samplestr
messagesize: equ 0x100
standardout: equ 0x01 ;stdout
standardin: equ 0x00 ;stdin
streamclose: equ 0x06
streamread: equ 0x03
streamwrite:   equ 0x04 ;Talking to the colonel
txtstoragesize: equ 0xFFFF  ;size of storage.
mydspace:   dq 0x0A,0x0A,0x00 ; double space output
lenmydspace: dq   $-mydspace
spacestring: dq   0x09,0x00 ; tab over from the left.
lenspacestr: dq   $-spacestring
myfilestring:   db   "Enter a file name and path:  ",0x00 ;String data.
lenmyfilestr:   dq   $-myfilestring   ;Get the length of the string.
ferrorstring:   dq "!!Buffer Overrun!!  ",0x00 ;String data.
lenferrorstr:   dq $-ferrorstring   ;Get the length of the string.
fconfstring:   dq "You have entered the file name:  ",0x00 ;String data.
lenfconfstr:   dq $-fconfstring   ;Get the length of the string.
fileattribs:   dq   "w",0x00 ;write to a file.
lenfileattribs: dq $-fileattribs
fileattribsrd:   dq   "r",0x00 ;read a file.
lenfileattribsrd: dq $-fileattribs



;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
; Beginning of executable code.
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&


SECTION .text


;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Printing Strings
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

main: mov rcx, 0x00 ; a simple loop to initialize storage.
.clearstr:   mov byte [varfilename + rcx], 0x00
inc rcx
mov rdx, 0xFF
cmp rcx,rdx
jne .clearstr

MOV rax, streamwrite ; Call the kernel
MOV rbx, standardout ; Specify command line output.
MOV rcx, mydspace   ; Load the location of the string.
MOV rdx, [lenmydspace] ;Load the length of the string.
INT 0x80 ` ; Call the operating system using an interrupt.

MOV rax, streamwrite ; Repeat as needed.
MOV rbx, standardout
MOV rcx, spacestring
MOV rdx, [lenspacestr]
INT 0x80 ; Call the kernel

MOV rax, streamwrite
MOV rbx, standardout
MOV rcx, myfilestring   ; Load the location of the string.
MOV rdx, [lenmyfilestr]
INT 0x80 ; Call the operating system using an interrupt.

;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
;                  Command Line Reads
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@


MOV dword [varlenfilename], 0x00 ; Initialize the length of the string.
.loop1: CALL getchar       ; Get a character
mov [tmpchr], eax
mov ebx, [varlenfilename]  ; put the string length in a register.
mov [varfilename + ebx], eax ;put the character in the memory.
INC ebx ;increment the index for the string.
MOV [varlenfilename], ebx ;put the index in memory
mov ecx, [tmpchr]
mov eax, 0x0A ; move a line feed into a register.
cmp eax, ecx ;  compare the two values.
jne .loop1 ; If not end of line go get another character.
mov ebx, [varlenfilename]
dec ebx
mov byte [varfilename + ebx], 0x00
inc ebx
mov [varlenfilename], ebx

;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Printing Strings
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

; Double space the line.

.next1: MOV rax, streamwrite ; Call the kernel
MOV rbx, standardout ; Specify the console
MOV rcx, mydspace  ; Load the location of the string.
MOV rdx, [lenmydspace] ;Load the length of the string.
INT 0x80 ; Call the operating system using an interrupt. ;Indent the line.

MOV rax, streamwrite ; Call the kernel
MOV rbx, standardout ; Specify the console
MOV rcx, spacestring  ; Load the location of the string.
MOV rdx, [lenspacestr] ;Load the length of the string.
INT 0x80 ; Call the operating system using an interrupt.

; Output an explanation string.
MOV rax, streamwrite
MOV rbx, standardout
MOV rcx, fconfstring
MOV rdx, [lenfconfstr]
INT 0x80 ;Output our newly captured string.

MOV rax, streamwrite
MOV rbx, standardout
MOV rcx, varfilename
MOV rdx, [varlenfilename]
INT 0x80

; Double space.
MOV rax, streamwrite ; Call the kernel
MOV rbx, standardout ; Specify the console
MOV rcx, mydspace  ; Load the location of the string.
MOV rdx, [lenmydspace] ;Load the length of the string.
INT 0x80 ; Call the operating system using an interrupt.
; Tab indent
MOV rax, streamwrite ; Call the kernel
MOV rbx, standardout ; Specify the console
MOV rcx, spacestring  ; Load the location of the string.
MOV rdx, [lenspacestr] ;Load the length of the strret
INT 0x80 ; Call the operating system using an interrupt.
; Using the captured string open a file.
jmp getdata


errorsarea:
.errorname: MOV rax, streamwrite ; Call the kernel
MOV rbx, standardout ; Write to the screen (kernel command).
MOV rcx, ferrorstring  ; Load the location of the string.
MOV rdx, [lenferrorstr] ;Load the length of the string.
INT 0x80 ; Call the operating system using an interrupt.

.fileerror: mov rax, streamwrite
MOV rbx, standardout
MOV rcx, fileerrorstr
MOV rdx, [lenfileerrorstr]
int 0x80

mov rax, [varfilepointer]
call clearerr
  mov rbx,rax
mov rax,0x00
cmp rax,rbx
je getdata
mov rax, 0x04
mov rbx, 0x01
mov rcx, fatalerror
mov rdx, lenfatalerror
int 0x80

.endthis: ret

;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
; Read a file with formatting.
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&


getdata: mov rcx, 0x00
mov qword [strlen], 0x00

.loop1: MOV rax, streamwrite ; Call the kernel
MOV rbx, standardout ; Specify the console
MOV rcx, mydspace  ; Load the location of the string.
MOV rdx, [lenmydspace] ;Load the length of the string.
INT 0x80 ; Call the operating system using an interrupt.

MOV rax, streamwrite ; Call the kernel
MOV rbx, standardout ; Specify the console
MOV rcx, spacestring  ; Load the location of the string.
MOV rdx, [lenspacestr] ;Load the length of the string.
INT 0x80 ; Call the operating system using an interrupt.

MOV rax, streamwrite ; Call the kernel
MOV rbx, standardout ; Specify the console
MOV rcx, mydspace  ; Load the location of the string.
MOV rdx, [lenmydspace] ;Load the length of the string.
INT 0x80 ; Call the operating system using an interrupt.

MOV rax, streamwrite ; Call the kernel
MOV rbx, standardout ; Specify the console
MOV rcx, spacestring  ; Load the location of the string.
MOV rdx, [lenspacestr] ;Load the length of the string.
INT 0x80 ; Call the operating system using an interrupt.

;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
;                  Command Line Reads
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

MOV qword [strlen], 0x00 ; Initialize the length of the string.
.loop2: call    getchar ; Get a character.
mov [tmpchr], rax
mov rbx, 0x7E
cmp rbx, rax
je openfile
mov ebx, [strlen]
mov rax, [tmpchr]
mov [ebx + txtstorage], rax
inc ebx
mov [strlen], ebx
jmp .loop2 ; keep reading characters.

;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Open a file for writing
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

openfile: MOV edi, varfilename ; Load the file name.
MOV esi, fileattribs ; Load the file attributes
call fopen ; Open the file
mov [varfilepointer], rax ; Save the file pointer.


;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
; Write data
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&


.loop1: mov rsi, [varfilepointer]
mov rdi, txtstorage
call fputs
mov rsi, [varfilepointer]
mov rdi, 0x7E
call fputc
.ender: mov rdi, [varfilepointer]
call fclose


;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Open and Echo a File
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

openread: mov ecx, 0x00
.clearstr:   mov byte [txtstorage + ecx], 0x00
inc ecx
mov edx, 0xFFFE
cmp ecx, edx
jne .clearstr  

MOV rdi, varfilename ; Load the file name.
MOV rsi, fileattribsrd ; Load the file attributes
call fopen ; Open the file
mov [varfilepointer], rax ; Save the file pointer
mov qword [offset], 0x00
.loop1: mov edi, [varfilepointer]
call getc
mov [tmpchr], eax
mov ecx, [offset]
mov [txtstorage + ecx], eax
inc ecx
mov [offset], ecx
mov edx, [docsize]
cmp ecx, edx
je .ender
mov edx, 0x0
mov ecx, [tmpchr]
cmp edx, ecx
jge .ender
mov edx, 0x7E
mov ecx, [tmpchr]
cmp edx, ecx
je .ender
mov edi, ecx
call putchar
jmp .loop1
.ender: ret

mov rdi, [varfilepointer]
call fclose

;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
; Print the data on the console.
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

mov rax, streamwrite
mov rbx, standardout
         mov rcx, txtstorage
mov rdx, [docsize]
int 0x80
ret

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; End of file
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Title: Re: Revamped 64 bit Code.
Post by: Keith Kanios on October 22, 2010, 04:42:11 PM
eberdeed: That is not the correct usage. Please read THIS (http://forum.nasm.us/index.php?action=help;page=post#bbcref) help page for information on how to use code blocks and other useful things.
Title: Re: Revamped 64 bit Code.
Post by: Frank Kotler on October 22, 2010, 06:47:52 PM
Thanks for trying, Ed. Square brackets (republican parentheses) - '[', ']', not angle brackets. It isn't quite html... but similar...

But I'm more worried about your code. Obviously, it must work - you'd notice, if it didn't - but you're calling the OS "the 32-bit way" (except using 64-bit registers). My understanding is that system call numbers have changed - 1 used to be "exit", now it's "write" and 3Ch is "exit" (no idea what we gained by that!) - and we do "syscall" instead of "int 80h" - and the parameters go in rsi, rdi, rdx, r10, r8, r9... Take a look at some of the sample programs here:

http://www.vikaskumar.org/amd64/index.htm

So I'm baffled that this is working! Can we use "old style" system calls if we use "int 80h"? Must be, but I'd never heard of it. I guess I'll have to get myself a 64-bit machine... some day soon...

Best,
Frank

Title: Re: Revamped 64 bit Code.
Post by: eberdeed on October 22, 2010, 07:58:11 PM
Thank you for the reference.  His prose is really dense, but I like the approach he uses.
Title: Re: Revamped 64 bit Code.
Post by: Bryant Keller on October 22, 2010, 09:20:14 PM
So I'm baffled that this is working! Can we use "old style" system calls if we use "int 80h"? Must be, but I'd never heard of it. I guess I'll have to get myself a 64-bit machine... some day soon...

I'm not. The 64-bit systems support 32-bit mode execution, what's happening is he's running along, doing normal 64-bit processing, then when he gets to "int 80h" the system jumps to the 32-bit compatibility handlers which just truncates/ignores everything except the lower 32-bits of the registers. This is completely fine to use as long as you are aware that your values are being truncated. Eventually you will run into a situation where a value calculated isn't the value you are expecting (due to this rounding off) and that's going to cause some real head-aches. My suggestion would be to either use 32-bit mode or use 64-bit mode, but dancing on the line like this (unless you have a really good reason to) isn't a very good idea.

Regards,
Bryant Keller
Title: Re: Revamped 64 bit Code.
Post by: eberdeed on October 22, 2010, 11:20:26 PM
I would like to thank everybody for their suggestions.  That last comment really hit the nail on the head for me.  I was wondering why my system kept sending me back to 32 bit land and the interrupt call sounds like the problem.   Well I spent the day with the http://www.vikaskumar.com website and came up with this.

Code: [Select]
; Edward C. Eberle
; San Diego, California  USA
; eberdeed@pacbell.net
; Language nasm (the Netwide Assembler)
; Created on a 64 bit Debian Linux System.
; Distributed under the GNU License.
; Welcome to 64 bit registries and stuff.
; This program echos back what is written at the
; command line.  It also produces a text file
; that is a copy of what was writen during
; the session.
;  I am indebted to the following website:
;  http://www.vikaskumar.org
;  Great assembly instruction.
; I would also like to thank Frank Kotler and Keith Kanios
; for their suggestions.

;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
; Macros
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

%macro prologue 0
        push    rbp
        mov     rbp,rsp
        push    rbx
        push    r12
        push    r13
        push    r14
        push    r15
%endmacro
%macro epilogue 0
        pop     r15
        pop     r14
        pop     r13
        pop     r12
        pop     rbx
        leave

%endmacro
;  These registers must be saved during a function call.
;  They are written as macros to save space.



BITS 64 ; Default to 64 bit alignment
GLOBAL main ; Program entry point
extern fgets ; C routines used to do the input and output.
extern fgetc
extern fopen
extern fputc
extern putchar
extern fputs
extern puts
extern fprintf
extern getc
extern ungetc
extern getchar
extern fclose
extern feof
extern ferror
extern clearerr
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
; Data Storage (Variables)
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

SECTION .bss
txtstorage: resq 0xFFFF
message: resq 0x100
varfilename: resq 0x100
varlenfilename: resq    0x01
varfilepointer: resq 0x01
docsize: resq 0x01
varfileaccess: resq 0x04
strlen: resq 0x01
tmpchr: resq 0x01
offset: resq 0x01
;countr: resd 0x01
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
; Fixed Data (Strings)
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

SECTION .data
fileerrorstr: dq "The program has had an Input -- Output error.",0x00
lenfileerrorstr: dd  $-fileerrorstr

fatalerror: dq "The program has made a fatal error.  END PROGRAM.",0x00
lenfatalerror: dd $-fatalerror

samplestr: dq "A good day!",0x00 ;The day.
lensamplestr:   dd $-samplestr

formatstr: dq "%s",0x00 ; fstrings format string.

messagesize: equ 0x100
standardout: equ 0x01 ;stdout

standardin: equ 0x00 ;stdin

streamclose: equ 0x06

streamread: equ 0x03
streamwrite:  equ 0x01 ;Talking to the colonel

txtstoragesize: equ 0xFFFF  ;size of storage.

mydspace:  dq 0x0A,0x0A,0x00 ; double space output
lenmydspace: dq  $-mydspace

spacestring: dq  0x09,0x00 ; tab over from the left.
lenspacestr: dq  $-spacestring

myfilestring:  db  "Enter a file name and path:  ",0x00 ;String data.
lenmyfilestr:  dq  $-myfilestring  ;Get the length of the string.

ferrorstring:  dq "!!Buffer Overrun!!  ",0x00 ;String data.
lenferrorstr:  dq $-ferrorstring  ;Get the length of the string.

fconfstring:  dq "You have entered the file name:  ",0x00 ;String data.
lenfconfstr:  dq $-fconfstring  ;Get the length of the string.

fileattribs:  dq  "w",0x00 ;read and write to a file.
lenfileattribs: dq $-fileattribs

fileattribsrd:  dq  "r",0x00 ;read and write to a file.
lenfileattribsrd: dq $-fileattribs


;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
; Beginning of executable code.
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

SECTION .text
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Printing Strings
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

main: mov rcx, 0x00
.clearstr:  mov byte [varfilename + rcx], 0x00
inc rcx
mov rdx, 0xFF
cmp rcx,rdx
jne .clearstr
prologue
mov rax, streamwrite ; Call the kernel
mov rdi, standardout ; Specify command line output.
mov rsi, mydspace  ; Load the location of the string.
mov rdx, [lenmydspace] ;Load the length of the string.
syscall ; Call the operating system
epilogue
prologue
mov rax, streamwrite ; Repeat as needed.
mov rdi, standardout
mov rsi, spacestring
mov rdx, [lenspacestr]
syscall
epilogue
prologue
mov rax, streamwrite ; Call the kernel
mov rdi, standardout
mov rsi, myfilestring  ; Load the location of the string.
mov rdx, [lenmyfilestr]
syscall ; Call the operating system using an interrupt.
epilogue
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
;                  Command Line Reads
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

mov dword [varlenfilename], 0x00 ; Initialize the length of the string.
.loop1: prologue
call getchar        ; Get a character
mov [tmpchr], rax
epilogue
mov rbx, [varlenfilename]  ; put the string length in a register.
mov [varfilename + rbx], rax ;put the character in the memory.
inc rbx ;increment the index for the string.
mov [varlenfilename], rbx ;put the index in memory
mov rcx, [tmpchr]
mov rax, 0x0A ; move a line feed into a register.
cmp rax, rcx ;  compare the two values.
jne .loop1 ; If not end of line go get another  character.
mov rbx, [varlenfilename]
dec rbx
mov byte [varfilename + rbx], 0x00
inc rbx
mov [varlenfilename], rbx

;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Printing Strings
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Double space the line.

.next1: prologue
mov rax, streamwrite ; Call the kernel
mov rdi, standardout ; Specify the console
mov rsi, mydspace  ; Load the location of the string.
mov rdx, [lenmydspace] ;Load the length of the string.
syscall ; Call the operating system using an interrupt.
epilogue
; Indent the line.
prologue
mov rax, streamwrite ; Call the kernel
mov rdi, standardout ; Specify the console
mov rsi, spacestring  ; Load the location of the string.
mov rdx, [lenspacestr] ;Load the length of the string.
syscall ; Call the operating system using an interrupt.
epilogue
; Output an explanation string.
prologue
mov rax, streamwrite
mov rdx, standardout
mov rsi, fconfstring
mov rdx, [lenfconfstr]
syscall
epilogue
; Output our newly captured string.
prologue
mov rax, streamwrite
mov rdi, standardout
mov rsi, varfilename
mov rdx, [varlenfilename]
syscall
epilogue
; Double space.
prologue
mov rax, streamwrite ; Call the kernel
mov rdi, standardout ; Specify the console
mov rsi, mydspace  ; Load the location of the string.
mov rdx, [lenmydspace] ;Load the length of the string.
syscall ; Call the operating system using an interrupt.
epilogue
; Tab indent
prologue
mov rax, streamwrite ; Call the kernel
mov rdi, standardout ; Specify the console
mov rsi, spacestring  ; Load the location of the string.
mov rdx, [lenspacestr] ;Load the length of the strret ;jmp openread.enditing.
syscall ; Call the operating system using an interrupt.
epilogue
; Using the captured string open a file.
jmp getdata
errorsarea:
.errorname:
prologue
mov rax, streamwrite ; Call the kernel
mov rdi, standardout ; Write to the screen (kernel command).
mov rsi, ferrorstring  ; Load the location of the string.
mov rdx, [lenferrorstr] ;Load the length of the string.
syscall ; C all the operating system using an interrupt.
epilogue
.fileerror:
prologue
mov rax, 0x04
mov rdi,0x01
mov rsi, fileerrorstr
mov rdx, [lenfileerrorstr]
syscall
epilogue
prologue
mov rax, [varfilepointer]
call clearerr
mov rbx,rax
epilogue
mov rax,0x00
cmp rax,rbx
je getdata
prologue
mov rax, 0x04
mov rdi, 0x01
mov rsi, fatalerror
mov rdx, lenfatalerror
syscall
epilogue
.endthis: ret


;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
; Read a file with formatting.ret ;jmp openread.endit
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
getdata: mov rcx, 0x00
mov qword [strlen], 0x00

.loop1: prologue
mov rax, streamwrite ; Call the kernel
mov rdi, standardout ; Specify the console
mov rsi, mydspace  ; Load the location of the string.
mov rdx, [lenmydspace] ;Load the length of the string.
syscall ; Call the operating system using an interrupt.
epilogue
prologue
mov rax, streamwrite ; Call the kernel
mov rdi, standardout ; Specify the console
mov rsi, spacestring  ; Load the location of the string.
mov rdx, [lenspacestr] ;Load the length of the string.
syscall ; Call the operating system using an interrupt.
epilogue
prologue
mov rax, streamwrite ; Call the kernel
mov rdi, standardout ; Specify the console
mov rsi, mydspace  ; Load the location of the string.
mov rdx, [lenmydspace] ;Load the length of the string.
syscall ; Call the operating system using an interrupt.
epilogue
prologue
mov rax, streamwrite ; Call the kernel
mov rdi, standardout ; Specify the console
mov rsi, spacestring  ; Load the location of the string.
mov rdx, [lenspacestr] ;Load the length of the string.
syscall ; Call the operating system using an interrupt.
epilogue
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
;                  Command Line Reads
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
mov qword [strlen], 0x00 ; Initialize the length of the string.
.loop2: prologue
call    getchar ; Get a character.
mov [tmpchr], rax
epilogue
mov rbx, 0x7E
cmp rbx, rax
je openfile
mov ebx, [strlen]
mov rax, [tmpchr]
mov [ebx + txtstorage], rax
inc ebx
mov [strlen], ebx
jmp .loop2 ; keep reading characters.


;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Open a file for writing
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

openfile:
prologue
mov rdi, varfilename ; Load the file name.
mov rsi, fileattribs ; Load the file attributes
call fopen ; Open the file
mov [varfilepointer], rax ; Save the file pointer.
epilogue

;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
; Write data
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

.loop1: prologue
mov rsi, [varfilepointer]
mov rdi, txtstorage
call fputs
epilogue
prologue
mov rsi, [varfilepointer]
mov rdi, 0x7E
call fputc
epilogue

.ender: prologue
mov rdi, [varfilepointer]
call fclose
epilogue

;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; Open and Echo a File
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

openread: mov ecx, 0x00
.clearstr: 
mov byte [txtstorage + ecx], 0x00
inc ecx
mov edx, 0xFFFE
cmp ecx, edx
jne .clearstr 
prologue
mov rdi, varfilename ; Load the file name.
mov rsi, fileattribsrd ; Load the file attributes
  call fopen ; Open the file
mov [varfilepointer], rax ; Save the file pointer
epilogue
mov qword [offset], 0x00
.loop1: prologue
mov edi, [varfilepointer]
call getc
mov [tmpchr], eax
epilogue
mov ecx, [offset]
mov [txtstorage + ecx], eax

inc ecx
mov [offset], ecx
mov edx, [docsize]
cmp ecx, edx
je .ender
mov edx, 0x0
mov ecx, [tmpchr]
cmp edx, ecx
jge .ender
mov edx, 0x7E
mov ecx, [tmpchr]
cmp edx, ecx
je .ender
mov edi, ecx
call putchar
jmp .loop1

.ender: prologue
mov rdi, [varfilepointer]
call fclose
epilogue
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
; Print the data on the console.
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
prologue
mov rax, streamwrite
mov rdi, standardout
        mov rsi, txtstorage
mov rdx, [docsize]
  syscall

mov rax, 0x3C
mov rdi, 0
syscall





;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; End of file
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Once again thanks.