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 に答える