2013-03-11 30 views
0

我想在MASM中转换下面的C++程序(目标是打开现有文件,在其中写入字符串并在最后读取文件):由于EAX寄存器中的句柄值太差,MASM ReadFile失败

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函数的值。我没有找到任何解决方案来保存由CreateFILE函数返回的eax的初始值,并在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 2013-03-11 22:21:55

相关问题