2013-03-11 2 views
0

Я хочу преобразовать следующую программу на C++ в MASM (цель состоит в том, чтобы открыть существующий файл, записать в него строку и в конце прочитать файл):Ошибка MASM ReadFile из-за плохого значения дескриптора в регистре EAX

void __cdecl _tmain(int argc, TCHAR *argv[]) 
{ 
    HANDLE  hFile; 

    ///////////////////////////////////////////////////////////////////////////////// 

    if ((hFile = CreateFile(TEXT("C:\\Users\\Bloodsucker94\\Desktop\\TestFile.txt"), 
         GENERIC_WRITE | GENERIC_READ, 
         FILE_SHARE_READ, 
         NULL, 
         OPEN_EXISTING, 
         FILE_ATTRIBUTE_NORMAL, 
         NULL)) == INVALID_HANDLE_VALUE) 
     _tprintf(TEXT("CreateFile() failed code %d\n"), GetLastError()); 

    ///////////////////////////////////////////////////////////////////////////////// 

    char  DataBuffer[1024] = "aaa"; 
    DWORD  dwBytesToWrite = (DWORD)strlen(DataBuffer); 
    DWORD  dwBytesWritten = 0; 

    //_tprintf(TEXT("CreateFile() HFILE=%d\n"), hFile); 

    if (WriteFile(hFile, DataBuffer, dwBytesToWrite, &dwBytesWritten, NULL) == FALSE) 
     _tprintf(TEXT("WriteFile() failed code %d\n"), GetLastError()); 

    //_tprintf(TEXT("WriteFile() HFILE=%d\n"), hFile); 

    ///////////////////////////////////////////////////////////////////////////////// 

    SetFilePointer(hFile, 0, NULL, FILE_BEGIN); 

    char  ReadBuffer[4096] = {0}; 
    DWORD  dwBytesRead; 

    if (FALSE == ReadFile(hFile, ReadBuffer, 4096, &dwBytesRead, NULL)) 
     _tprintf(TEXT("ReadFile() failed code %d\n"), GetLastError()); 

    printf("|%s|", ReadBuffer); 

    getchar(); 
    CloseHandle(hFile); 
} 

код ASM:

.386 
.model flat, stdcall 
option casemap :none 

include       \masm32\include\windows.inc 
include       \masm32\include\kernel32.inc 
include       \masm32\include\masm32.inc 
includelib      \masm32\lib\kernel32.lib 
includelib      \masm32\lib\masm32.lib 
include       \masm32\include\msvcrt.inc 
includelib      \masm32\lib\msvcrt.lib 

.data 

FileName      BYTE       "HelloWorld.txt", 0 
BufferToWrite     BYTE       "Hell yeaahhhhhh!!!!", 0 
ErrorCreateMsgFormat   BYTE       "CreateFile() failed with code %d", 0 
ErrorReadMsgFormat    BYTE       "ReadFile() failed with code %d", 0 
ErrorWriteMsgFormat    BYTE       "WriteFile() failed with code %d", 0 
CheckFormat      BYTE       "hFile=%d", 0 
CheckSize      BYTE       "size=%d", 0 
CheckPtr      BYTE       "EAX_ADDR=Ox%08X", 0 
OutputFormat     BYTE       "output=%s", 0 

.data? 

hFile       HANDLE       ? 
hFileCopy      HANDLE       ? 
FileSize      DWORD       ? 
hMem       LPVOID       ? 
BytesRead      LPDWORD       ? 
ErrorCode      DWORD       ? 
RetRead       BOOL       ? 
RetWrite      BOOL       ? 
NumberOfBytesToWrite   DWORD       ? 
NumberOfBytesWritten   DWORD       ? 
BufferToWriteSize    DWORD       ? 

.code 

start: 
    invoke lstrlen,   ADDR BufferToWrite 
    mov  BufferToWriteSize, eax 

    ;-----------------------------CREATE------------------------------- 

    invoke CreateFile,   ADDR FileName,     \ 
           GENERIC_WRITE + GENERIC_READ, \ 
           0,        \ 
           NULL,       \ 
           OPEN_EXISTING,     \ 
           FILE_ATTRIBUTE_NORMAL,   \ 
           NULL 

    mov  hFile,    eax 

    .IF hFile == INVALID_HANDLE_VALUE 
      invoke    GetLastError 
      mov ErrorCode,  eax 
      invoke crt_printf, ADDR ErrorCreateMsgFormat,  \ 
           ErrorCode 
      jmp     _quit 
    .ENDIF 

    invoke crt_printf,   ADDR CheckFormat,    \ 
           hFile 


    ;---------------------------WRITE--------------------------------- 


    invoke WriteFile,   hFile,       \ 
           ADDR BufferToWrite,    \ 
           BufferToWriteSize,    \ 
           ADDR NumberOfBytesWritten,  \ 
           NULL 

    mov  RetWrite,   eax 

    .IF RetWrite == FALSE 
      invoke    GetLastError 
      mov ErrorCode,  eax 
      invoke crt_printf, ADDR ErrorWriteMsgFormat,  \ 
           ErrorCode 
      jmp     _quit 
    .ENDIF 

    invoke crt_printf,   ADDR CheckFormat,    \ 
           hFile 

    ;--------------------------READ---------------------------------- 

    invoke GetFileSize,  eax,       \ ;problem start here 
           NULL 

    mov  FileSize,   eax 
    inc  eax 

    invoke crt_printf,   ADDR CheckSize,     \ 
           FileSize 

    invoke GlobalAlloc,  GMEM_FIXED,      \ 
           eax 

    mov  hMem,    eax 
    add  eax,    FileSize 

    mov  BYTE PTR [eax],  0 

    invoke ReadFile,   hFile,       \ 
           hMem,       \ 
           FileSize,      \ 
           ADDR BytesRead,     \ 
           NULL 

    mov  RetRead,   eax 

    .IF RetRead == FALSE 
      invoke    GetLastError 
      mov ErrorCode,  eax 
      invoke crt_printf, ADDR ErrorReadMsgFormat,  \ 
           ErrorCode 
      jmp     _quit 
    .ENDIF 

    invoke crt_printf,   ADDR CheckFormat,    \ 
           hFile 

    invoke crt_printf,   ADDR OutputFormat,    \ 
           hMem 

    invoke CloseHandle,  hFile 
    invoke GlobalFree,   hMem 

_quit: 
    invoke ExitProcess,  0 

end start 

проблема заключается в EAX регистр не содержит возвращаемое значение CreateFile (hFile). Это нормально, потому что он содержит в точке выполнения значение функции WriteFile. Я не нашел решения для сохранения начального значения eax, возвращаемого функцией CreatefILE, и использовать его снова после вызова функции WriteFile. Я не могу это сделать:

mov  FileSize,   hFile 

Я просто хочу, чтобы сохранить первое значение EAX. Я попытался сохранить его в другой регистр, но он не работает. Кто-нибудь может мне помочь?

ответ

0

Eiher:

.data 
savedValue DWORD ? 

.code 
… 
// save to a variable 
mov savedValue, eax 
… 
// restore from a variable 
mov eax, savedValue 
… 

или:

.code 
… 
// save to stack 
push eax 
… 
// restore from stack 
pop eax 
… 

Извините за ошибки синтаксиса. Это было долгое время с момента последнего обычного использования для непосредственного использования.

+0

Согласно вашему совету, я добавил ligne кода: mov eax, hFile, чтобы вернуть первое значение eax, и оно отлично работает! Большое спасибо за Вашу помощь. До свидания! – user1364743