Author Topic: 64 Bit + C file IO  (Read 26795 times)

Offline eberdeed

  • Jr. Member
  • *
  • Posts: 9
64 Bit + C file IO
« on: October 19, 2010, 03:08:58 AM »
Code: [Select]
; 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 :)
« Last Edit: October 19, 2010, 06:40:07 PM by Keith Kanios »

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: 64 Bit + C file IO
« Reply #1 on: October 19, 2010, 12:30:08 PM »
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


Offline cm

  • Jr. Member
  • *
  • Posts: 65
Re: 64 Bit + C file IO
« Reply #2 on: October 19, 2010, 03:20:09 PM »
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.
C. Masloch

Offline eberdeed

  • Jr. Member
  • *
  • Posts: 9
Re: 64 Bit + C file IO
« Reply #3 on: October 19, 2010, 03:54:14 PM »
If you look carefully you will see that all the string storage is byte.  The program does work, I can vouch for that.

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: 64 Bit + C file IO
« Reply #4 on: October 19, 2010, 04:56:22 PM »
Perhaps I'm not looking carefully enough...

Code: [Select]
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"...

Code: [Select]
   MOV   rcx, fileerrorstr
   MOV   rdx, [lenfileerrorstr]

If it works, it works, but this doesn't look "right" to me!

Best,
Frank


Offline eberdeed

  • Jr. Member
  • *
  • Posts: 9
Re: 64 Bit + C file IO
« Reply #5 on: October 21, 2010, 01:30:38 AM »
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

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.

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
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
« Last Edit: October 21, 2010, 03:51:42 PM by Keith Kanios »

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: 64 Bit + C file IO
« Reply #6 on: October 21, 2010, 10:32:18 AM »
Hi Ed,

Maybe I'm even farther over my head than I realize.

This looks correct to me:

Code: [Select]
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!

Code: [Select]
   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.

Code: [Select]
.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


Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: 64 Bit + C file IO
« Reply #7 on: October 21, 2010, 10:55:06 AM »
I really don't know what I'm doing here, but I just can't let this go...

Quote
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...


Offline Keith Kanios

  • Full Member
  • **
  • Posts: 383
  • Country: us
    • Personal Homepage
Re: 64 Bit + C file IO
« Reply #8 on: October 21, 2010, 03:54:16 PM »
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.

Offline eberdeed

  • Jr. Member
  • *
  • Posts: 9
Re: 64 Bit + C file IO
« Reply #9 on: October 22, 2010, 06:34:16 PM »
One more time with the code blocks

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
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


That's kind of nifty.

Ed Eberle

Offline eberdeed

  • Jr. Member
  • *
  • Posts: 9
Re: 64 Bit + C file IO
« Reply #10 on: October 22, 2010, 06:48:30 PM »
I didn't like how the embedded tabs showed up, so here it is yet once again.

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
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~



There be yea.

Offline Bryant Keller

  • Forum Moderator
  • Full Member
  • *****
  • Posts: 360
  • Country: us
    • About Bryant Keller
Re: 64 Bit + C file IO
« Reply #11 on: October 22, 2010, 09:48:02 PM »
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:

Code: [Select]
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:

Code: [Select]
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!

Code: [Select]
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.

About Bryant Keller
bkeller@about.me

Offline cm

  • Jr. Member
  • *
  • Posts: 65
Re: 64 Bit + C file IO
« Reply #12 on: October 22, 2010, 10:52:53 PM »
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:

Code: [Select]
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.
C. Masloch