generating random numbers and writing them to a file in assembler (WriteFile, ReadFile)

Viewed 78

in my program, I need to generate 20 random numbers and write them to a file (file.dat) and then also read them from there. so far I do not quite understand how to write many numbers and am trying to write only one. and so, I successfully generate a random number and even write it to a file, but when reading a number from a file, for some reason it is not written to a variable (bufforNumbersRead).

.586P
.MODEL flat, STDCALL
;--- stale z pliku .\include\windows.inc ---
STD_INPUT_HANDLE                     equ -10
STD_OUTPUT_HANDLE                    equ -11
GENERIC_READ                         equ 80000000h
GENERIC_WRITE                        equ 40000000h
CREATE_NEW                           equ 1
CREATE_ALWAYS                        equ 2
OPEN_EXISTING                        equ 3
OPEN_ALWAYS                          equ 4
TRUNCATE_EXISTING                    equ 5
FILE_FLAG_WRITE_THROUGH              equ 80000000h
FILE_FLAG_OVERLAPPED                 equ 40000000h
FILE_FLAG_NO_BUFFERING               equ 20000000h
FILE_FLAG_RANDOM_ACCESS              equ 10000000h
FILE_FLAG_SEQUENTIAL_SCAN            equ 8000000h
FILE_FLAG_DELETE_ON_CLOSE            equ 4000000h
FILE_FLAG_BACKUP_SEMANTICS           equ 2000000h
FILE_FLAG_POSIX_SEMANTICS            equ 1000000h
FILE_ATTRIBUTE_READONLY              equ 1h
FILE_ATTRIBUTE_HIDDEN                equ 2h
FILE_ATTRIBUTE_SYSTEM                equ 4h
FILE_ATTRIBUTE_DIRECTORY             equ 10h
FILE_ATTRIBUTE_ARCHIVE               equ 20h
FILE_ATTRIBUTE_NORMAL                equ 80h
FILE_ATTRIBUTE_TEMPORARY             equ 100h
FILE_ATTRIBUTE_COMPRESSED            equ 800h
FORMAT_MESSAGE_ALLOCATE_BUFFER       equ 100h
FORMAT_MESSAGE_IGNORE_INSERTS        equ 200h
FORMAT_MESSAGE_FROM_STRING           equ 400h
FORMAT_MESSAGE_FROM_HMODULE          equ 800h
FORMAT_MESSAGE_FROM_SYSTEM           equ 1000h
FORMAT_MESSAGE_ARGUMENT_ARRAY        equ 2000h
FORMAT_MESSAGE_MAX_WIDTH_MASK        equ 0FFh
FILE_BEGIN                           equ 0h ;MoveMethod dla SetFilePointe
FILE_CURRENT                         equ 1h ;MoveMethod dla SetFilePointe
FILE_END                             equ 2h ;MoveMethod dla SetFilePointe

;--- funkcje API Win32 z pliku  .\include\user32.inc ---
CharToOemA PROTO :DWORD,:DWORD
;--- z pliku .\include\kernel32.inc ---
GetStdHandle PROTO :DWORD
ReadConsoleA PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD
WriteConsoleA PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD
ExitProcess PROTO :DWORD
wsprintfA PROTO C :VARARG     ;; int wsprintf(LPTSTR lpOut,// pointer to buffer for output 
                              ;; LPCTSTR lpFmt,// pointer to format-control string 
                              ;;    ... // optional arguments  );
lstrlenA PROTO :DWORD
GetCurrentDirectoryA PROTO :DWORD,:DWORD  
      ;;nBufferLength, lpBuffer; zwraca length
CreateDirectoryA PROTO :DWORD,:DWORD      
      ;;lpPathName, lpSecurityAttributes; zwraca 0 jeœli b³ad
lstrcatA PROTO :DWORD,:DWORD              
      ;; lpString1, lpString2; zwraca lpString1
CreateFileA PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD 
      ;; LPCTSTR lpszName, DWORD fdwAccess, 
      ;; DWORD fdwShareMode, LPSECURITY_ATTRIBUTES lpsa, DWORD fdwCreate, 
      ;; DWORD fdwAttrsAndFlags, HANDLE hTemplateFile
lstrcpyA PROTO :DWORD,:DWORD  
      ;;LPTSTR lpString1 // address of buffer, LPCTSTR lpString2    // address of string to copy 
CloseHandle PROTO :DWORD      
      ;; BOOL CloseHandle(HANDLE hObject)
WriteFile PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD    
   ;; BOOL WriteFile(
   ;; HANDLE hFile, // handle to file to write to
   ;; LPCVOID lpBuffer, // pointer to data to write to file
   ;; DWORD nNumberOfBytesToWrite,  // number of bytes to write
   ;; LPDWORD lpNumberOfBytesWritten,   // pointer to number of bytes written
   ;; LPOVERLAPPED lpOverlapped     // pointer to structure needed for overlapped I/O 
   ;;);
ReadFile PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD
    ;;BOOL ReadFile(
    ;;HANDLE hFile, // handle of file to read 
    ;;LPVOID lpBuffer,  // address of buffer that receives data  
    ;;DWORD nNumberOfBytesToRead,   // number of bytes to read 
    ;;LPDWORD lpNumberOfBytesRead,  // address of number of bytes read 
    ;;LPOVERLAPPED lpOverlapped     // address of structure for data 
    ;;);
CopyFileA PROTO :DWORD,:DWORD,:DWORD      
    ;; BOOL CopyFile(
    ;;LPCTSTR lpExistingFileName,   // pointer to name of an existing file 
    ;;LPCTSTR lpNewFileName,    // pointer to filename to copy to 
    ;;BOOL bFailIfExists    // flag for operation if file exists  
    ;;);
GetLastError PROTO

GetTickCount PROTO
;--- z pliku ..\include\masm32.inc ---
nseed PROTO :DWORD
nrandom PROTO :DWORD


dwtoa PROTO dwValue:DWORD, lpBuffer:DWORD ;dwtoa convert a DWORD value to an ascii string.
;dwtoa proc dwValue:DWORD, lpBuffer:DWORD   
atodw  PROTO lpBuffer:DWORD ;atodw converts a decimal string to dword.
;atodw proc String:PTR BYTE
StripLF PROTO :DWORD ;StripLF is designed to remove the CRLF (ascii 13,10) by writing an ascii zero in the place of the first occurrence of ascii 13.
;StripLF proc strng:DWORD
StdIn PROTO :DWORD,:DWORD ;StdIn receives text input from the console and places it in the buffer required as a parameter. The function terminates when Enter is pressed.
;StdIn proc lpszBuffer:DWORD,bLen:DWORD
StdOut PROTO :DWORD ;StdOut will display a zero terminated string at the current position in the console.
;StdOut proc lpszText:DWORD
;--- funkcje
;------------s
;includelib .\lib\user32.lib
;includelib .\lib\kernel32.lib
;includelib .\lib\masm32.lib
;-------------
_DATA SEGMENT

    folderName BYTE "/newFolder", 0
    fileName BYTE "/file.dat", 0
    buffor BYTE 250 dup(0)

    randomNumber DD ?
    writtenBytes DD ?
    writtenBytes2 DD ?
    handleFile DD ?
    bufforNumbers DD 250 dup(0)
    bufforNumbersRead DD 250 dup(0)

_DATA ENDS
;------------
_TEXT SEGMENT
main proc

; -- creating folder "newFolder" --
    push OFFSET buffor
    push 255
    call GetCurrentDirectoryA

    push OFFSET folderName
    push OFFSET buffor
    call lstrcatA

    push 0
    push OFFSET buffor
    call CreateDirectoryA
; -- end --

; -- generating random numbers --
    call GetTickCount
    push eax 
    call nseed

    mov ecx, 1
    generateRandomNumbers:
    push ecx

    ;--- generating random numbers from 0 to 99 ---
        push 9
        call nrandom
        mov bufforNumbers, eax 

    pop ecx
    loop generateRandomNumbers
; -- end -- 

; -- creating file "file.dat" --
    push OFFSET buffor
    push 255
    call GetCurrentDirectoryA

    push OFFSET fileName
    push OFFSET buffor
    call lstrcatA

    push 0
    push 0
    push CREATE_ALWAYS
    push 0
    push 0
    push GENERIC_WRITE
    push OFFSET buffor
    call CreateFileA

    mov handleFile, eax
; -- end --

; -- write in file numbers --
    push 0
    push writtenBytes
    push 1    
    push OFFSET bufforNumbers
    push eax
    call WriteFile
; -- end --

;-- read file --
    push 0
    push writtenBytes2
    push 1
    push OFFSET bufforNumbersRead
    push handleFile
    call ReadFile
; -- end --

    push 0
    call ExitProcess
main endp
_TEXT   ENDS
END
1 Answers

You can't call ReadFile right after WriteFile with the same handle and expect to get back what you just wrote. You must seek back with SetFilePointer before reading.

You should also check the return value after calling a function...

Related