【问题标题】:generating random numbers and writing them to a file in assembler (WriteFile, ReadFile)生成随机数并将它们写入汇编程序中的文件(WriteFile,ReadFile)
【发布时间】:2021-12-14 01:51:08
【问题描述】:

在我的程序中,我需要生成 20 个随机数并将它们写入文件 (file.dat),然后从那里读取它们。到目前为止,我不太明白如何写很多数字,我只想写一个。因此,我成功生成了一个随机数,甚至将其写入文件,但是从文件中读取数字时,由于某种原因,它没有写入变量(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

【问题讨论】:

标签: windows winapi assembly x86


【解决方案1】:

您不能在WriteFile 之后使用相同的句柄调用ReadFile 并期望取回您刚刚写的内容。在阅读之前,您必须通过SetFilePointer 回溯。

你还应该在调用函数后检查返回值...

【讨论】:

  • 最好在OVERLAPPED 中使用显式文件偏移,而不是SetFilePointer
猜你喜欢
  • 2018-09-19
  • 1970-01-01
  • 2020-07-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多