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 の最初の値を保存したいだけです。別のレジスタに保存しようとしましたが、うまくいきません。誰でも私を助けることができますか?