NASM - The Netwide Assembler
NASM Forum => Example Code => Topic started by: eberdeed on October 19, 2010, 03:08:58 AM
-
; Edward C. Eberle
; San Diego, California USA
; eberdeed@eberdeed.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. It uses the tilde 0x7E ~
; as the end of file marker.
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: resb 0xFFFF
message: resb 0x100
varfilename: resb 0x100
varlenfilename: resd 0x01
varfilepointer: resq 0x01
docsize: resq 0x01
varfileaccess: resb 0x04
strlen: resd 0x01
tmpchr: resd 0x01
offset: resd 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 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: dq "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
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
MOV rax, streamwrite ; Call the kernel
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 ;jmp openread.enditing.
INT 0x80 ; Call the operating system using an interrupt.
; Using the captured string open a file.
jmp getdata
errorsarea:
.errorname: MOV rax, 0x04 ; Call the kernel
MOV rbx, 0x01 ; 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 ; C all the operating system using an interrupt.
.fileerror: mov rax, 0x04
MOV rbx,0x01
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.ret ;jmp openread.endit
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
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
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Here is a bash script to compile the blessed thing.
#!/bin/bash
nasm -g -felf64 -Ox -i/usr/include/ -WALL -ofilestringwrt.o filestringwrt.asm
gcc -gstabs -ofilestringwrt filestringwrt.o -Istdio.h
exit
Edit: Code blocks are your friend :)
-
I don't know much about 64-bit code, but I was under the impression that the system call numbers had changed. Do we really need to declare strings "dq"? Does this thing actually work?
Best,
Frank
-
Do we really need to declare strings "dq"? Does this thing actually work?
No. There's no 64-bit string encoding, so dq is plain wrong for strings.
-
If you look carefully you will see that all the string storage is byte. The program does work, I can vouch for that.
-
Perhaps I'm not looking carefully enough...
fileerrorstr: dq "The program has had an Input -- Output error.",0x00
lenfileerrorstr: dd $-fileerrorstr
That doesn't look like "byte" to me! Some of your lengths are "dd" and some are "dq"...
MOV rcx, fileerrorstr
MOV rdx, [lenfileerrorstr]
If it works, it works, but this doesn't look "right" to me!
Best,
Frank
-
I went ahead and converted it all to quad words. By the way, I did some research and this is required on my system because I am using
that utf-8 encoding and apparently, where under a 32 bit system it would count the bytes used and adjust accordingly, under a 64 bit system it just defaults to a quad word. When I run it with byte size strings it refuses to acknowledge the NULL at the end of the line and just starts printing all the stored text.
Ed Eberle
; 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.
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 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 ;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
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
MOV rax, streamwrite ; Call the kernel
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 ;jmp openread.enditing.
INT 0x80 ; Call the operating system using an interrupt.
; Using the captured string open a file.
jmp getdata
errorsarea:
.errorname: MOV rax, 0x04 ; Call the kernel
MOV rbx, 0x01 ; 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 ; C all the operating system using an interrupt.
.fileerror: mov rax, 0x04
MOV rbx,0x01
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.ret ;jmp openread.endit
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
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
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
Hi Ed,
Maybe I'm even farther over my head than I realize.
This looks correct to me:
myfilestring: db "Enter a file name and path: ",0x00 ;String data.
lenmyfilestr: dq $-myfilestring ;Get the length of the string.
Does it work?
This code definitely looks like an error to me!
mov rax, 0x04
mov rbx, 0x01
mov rcx, fatalerror
mov rdx, lenfatalerror
int 0x80
Presumably, it doesn't get exercised. If it did, it would spew all subsequent text... and then probably segfault.
The code following the first "ret" appears never to be executed.
.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
But I'm not going to argue with success. If it works, it works!
Best,
Frank
-
I really don't know what I'm doing here, but I just can't let this go...
When I run it with byte size strings it refuses to acknowledge the NULL at the end of the line and just starts printing all the stored text.
Where does this happen, Ed. I don't see where you're printing a NULL-terminated string.
Best,
Frank
P.S. If you wish to use those "code tags", put in square brackets (like it was a memory reference in Nasm), "code"... and "/code" at the end of it...
-
P.S. If you wish to use those "code tags", put in square brackets (like it was a memory reference in Nasm), "code"... and "/code" at the end of it...
eberdeed: It is less of a suggestion and more of a demand. Use code tags/blocks, as posting that much textual information is simply obnoxious.
-
One more time with the code blocks
; 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
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
That's kind of nifty.
Ed Eberle
-
I didn't like how the embedded tabs showed up, so here it is yet once again.
; 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
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
There be yea.
-
You've got things seriously mixed up in regards to strings and I think it's because of a separation of what I call "Linux Strings" versus "ASCIIZ Strings". ASCIIZ Strings are arrays of BYTES followed by a NULL terminator. So say we want an ASCIIZ string to say Hello, World!, in NASM we can define it as:
strHello: db "Hello, World!", 0x00
Pay close attention to this. the DB specifies that we are defining a series of BYTE values. So each character is 1 Byte. The NULL terminator is of course specified at the end. These types of strings are used with your GNU C LIbrary functions like fprintf().
The other type, the ones I call "Linux Strings" aren't defined quite the same. Linux Strings are arrays of bytes and a LOGICAL length association. So what does this mean? Lets check out our Hello, World! example:
strHello: db "Hello, World!"
lenHello equ ($-strHello)
Now notice with these you don't need a NULL terminator because we have a logical length association (lenHelloWorld in this example). These types of strings are to be used with the Linux kernel interrupts which require a string address and a length specification. So what can we do to make things easier? A Combination!
strHello: db "Hello, World!", 0
lenHello equ ($-(strHello)-1)
The string created is a BYTE array with a NULL terminator, but it has a LOGICAL length association whose value is 1 less than the true length (removing the null terminator). So now, if you have to use strHello with a Linux interrupt or a C function, you're covered.
Now, there may be more wrong with your code, I will admit that I've not given it a proper look over. This is just the first thing that stuck out when I glanced over it. I hope it helps.
-
The usage of dq to define strings is incorrect, but with this code, NASM behaves in a way that makes it appear to work. Here's an example:
dq "some string",0
This outputs 24 bytes - the string "some string" (as would be expected from db) followed by 13 zero bytes. The last 8 zero bytes are the output of the zero terminator as might be expected. The other 5 zero bytes are padding, because using dq to output strings means they will be zero-padded to a multiple of 8 bytes. Linux apparently ignores zeros that are displayed (or maybe it displays them as space or something) so your program appears to work as desired. Still, db would be the right directive to declare strings, not dq.