0

我想在 MASM 中转换以下 C++ 程序(目标是打开一个现有文件,向其中写入一个字符串,最后读取文件):

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 的第一个值。我试图将它保存到另一个寄存器中,但它不起作用。有人可以帮助我吗?

4

1 回答 1

0

要么:

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

抱歉有任何语法错误。距离上一个直接组装使用的常见用例已经有很长时间了。

于 2013-03-11T21:52:34.170 回答