Hey all,
I'm just starting to take up assembly as a hobby after working with higher level languages such as Python and Java for years. As i devel into Assembly it seems quite elegant in its extreme, raw, simplicity.
Anyways, with my first project, I'm trying to read a file, and use the user32 MessageBox to display the information.
Im thinking my problem might be a type mistmatch (If you have them in Assembler, Like I said i'm and infant in this language).
.486
.model flat, stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\masm32.inc
include \masm32\include\user32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\masm32.lib
.data
logfile db "test.log",0
.data?
hLog HANDLE ? ; File handle
temp_buffer db 32768 dup(?)
SizeReadWrite DWORD ? ; number of bytes actually read or write
.code
start:
invoke CreateFile,ADDR logfile, GENERIC_READ , FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_ARCHIVE, NULL
mov hLog,eax
invoke ReadFile,hLog,temp_buffer, 16, ADDR SizeReadWrite,NULL ; Size hardcoded
invoke MessageBox,0,temp_buffer ,"Test",0
invoke CloseHandle,hLog
end start
Thanks in advance,
--Joel
Hello Joel, welcome to the group. :toothy
Code looks pretty good, have you tried running it in a debugger such as OllyDbg (http://www.ollydbg.de/) yet? CreateFile and ReadFile are very particular about their flags and permissions. Stepping through each instruction (F8 in Olly) can "show" you what happens on nearly a line-by-line basis - very helpful for isolating issues.
There might be a few caveats with the program as it is written (I can't test it at the moment.) One is that the MessageBox API will only display a set quantity of text. If you try to display more than it can hold (about 1k probably), it will just exit with an (unhandled) error.
There are a few errors in the line
invoke MessageBox,0,temp_buffer ,"Test",0
If you look up the MessageBox API at MSDN or in the Win32.HLP file, it shows the string parameters as "lpText" and "lpCaption." The lp basically stands for pointer, so that token should be a pointer and not a value, so try ADDR temp_buffer.
Quotations are not allowed in INVOKE statements. You can try replacing INVOKE with FN, which is a macro like invoke which allows quotations. That might do the trick. You'll need to include \masm32\macros\macros.asm
Finally you might want to consider allocating large buffers dynamically using routines like masm32's STRALLOC and STRFREE or Windows' GlobalAlloc and related. The .data? section is intended primarily for global uninitialized variables, not large buffers (it should work either way though.) Have fun! :U
Also, you need to properly end the process, normally done with a call to ExitProcess.
If the Message Box caption "Error" is acceptable you can pass NULL in the lpCaption parameter.
Try to change these lines to this:
invoke ReadFile,hLog,addr temp_buffer, 16, ADDR SizeReadWrite,NULL ; Size hardcoded
invoke MessageBox,0,addr temp_buffer ,"Test",0
I am not sure what macro you are using for the "Test" but if your not that is wrong too.
Zcoder....
Joel,
Welcome on board. Here is a quick fix that works.
.486
.model flat, stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\masm32.inc
include \masm32\include\user32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\masm32.lib
.data
logfile db "test.log",0
msgbox_title db "Test",0
.data?
hLog HANDLE ? ; File handle
temp_buffer db 32768 dup(?)
fsiz dd ?
SizeReadWrite DWORD ? ; number of bytes actually read or write
.code
start:
invoke CreateFile,ADDR logfile,GENERIC_READ,
FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_ARCHIVE,NULL
mov hLog,eax
invoke GetFileSize,hLog,NULL
mov fsiz, eax
invoke ReadFile,hLog,ADDR temp_buffer,fsiz, ADDR SizeReadWrite,NULL
invoke MessageBox,0,ADDR temp_buffer,ADDR msgbox_title,0
invoke CloseHandle,hLog
invoke ExitProcess,0
end start
See extra version below.
It also good to use GetFileAttributes before CreateFile, since there is possibilities that attributes you assumed for the file wouldn't match the factual ones.
Thanks to all of you.
I think I'm still treating the lanuage like i'de treat a higher level language, and i need to start thinking outside of my abstracted box :lol
Thank you yet again, you all are part of a very welcoming community.
--Joel
Hutch,
The second example you post, the one that will open any size file will not assemble. He will not be able to assemble it because temp_buffer is missing.
Paul
Thanks Paul,
I appear to have resaved a version that was only partly modified. I get caught that way occasionally with multiple copies of the same source.
here is the fix.
.486
.model flat, stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\masm32.inc
include \masm32\include\user32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\masm32.lib
.data
logfile db "test.log",0
msgbox_title db "Test",0
.code
; --------------------------------------------------
start:
call main
invoke ExitProcess,0
; --------------------------------------------------
main proc
LOCAL hLog :DWORD ; file handle
LOCAL fsiz :DWORD ; file size
LOCAL bwrt :DWORD ; bytes written
LOCAL hMem :DWORD ; memory handle
invoke CreateFile,ADDR logfile,GENERIC_READ,
FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_ARCHIVE,NULL
mov hLog, eax
invoke GetFileSize,hLog,NULL ; get the file size
mov fsiz, eax
sub fsiz, 1
invoke GlobalAlloc,GMEM_FIXED,fsiz ; allocate at least that much memory
mov hMem, eax
invoke ReadFile,hLog,hMem,fsiz,ADDR bwrt,NULL
invoke MessageBox,0,hMem,ADDR msgbox_title,0
invoke CloseHandle,hLog ; close the file handle
invoke GlobalFree,hMem ; free the allocated memory
ret
main endp
; --------------------------------------------------
end start
That definitely works, but have you tried it with a large file? It is not very usuable without scrollbars!
Paul
:bg
You are right, a MessageBox is not suited for large text display but i did not want to change the original example too much or make it too complicated.