Hi guys,
I have a project to do in wich i must use a variable(byte) which is in a binary file so I must read for example the first byte or any byte depending on the port i want to read from,how should I do this?
Thanks
use CreateFile to open the file
use SetFilePointer or SetFilePointerEx to set the file pointer
use ReadFile to read the byte into a buffer
use CloseHandle to close the file handle
http://msdn.microsoft.com/en-us/library/windows/desktop/aa363858%28v=vs.85%29.aspx (http://msdn.microsoft.com/en-us/library/windows/desktop/aa363858%28v=vs.85%29.aspx)
http://msdn.microsoft.com/en-us/library/windows/desktop/aa365541%28v=vs.85%29.aspx (http://msdn.microsoft.com/en-us/library/windows/desktop/aa365541%28v=vs.85%29.aspx)
http://msdn.microsoft.com/en-us/library/windows/desktop/aa365542%28v=vs.85%29.aspx (http://msdn.microsoft.com/en-us/library/windows/desktop/aa365542%28v=vs.85%29.aspx)
http://msdn.microsoft.com/en-us/library/windows/desktop/aa365467%28v=vs.85%29.aspx (http://msdn.microsoft.com/en-us/library/windows/desktop/aa365467%28v=vs.85%29.aspx)
http://msdn.microsoft.com/en-us/library/windows/desktop/ms724211%28v=vs.85%29.aspx (http://msdn.microsoft.com/en-us/library/windows/desktop/ms724211%28v=vs.85%29.aspx)
use the forum search tool for examples of each function
or - use Windows Explorer search tool to look in masm32\examples for files containing those function names
if you like, you can do it without setting the file pointer
make the buffer large enough to read the entire file up to the desired byte
then access the buffer at the desired offset
I ve found the fileio example from masm32 but it doesn't t help me because it reads from a text file and not from a binary file in which I have a number of ports and each port is represented by a byte.I must get the byte that is in port 0 that means the first byte and put it into a variable in my program.
In MASM it doesn't matter what the underlying format is, you always read BYTES. You can then determine what to do with that BYTE data. In your case, just read and use the first BYTE.
Dave.
Here is a complete example that reads one byte from a known file. We expect that byte to be "M" (Ascii 77) as in "MZ" ;-)
include \masm32\include\masm32rt.inc
.code
start:
; open a file - the handle returned in eax gets pushed on the stack:
push fopen("\Masm32\examples\exampl05\hlldemo\fileio\fileio.exe")
push 0 ; create an empty 4-byte buffer on the stack
mov ecx, esp ; and store its address to ecx
push eax ; create another 4-byte buffer on the stack
mov edx, esp ; and store its address to edx
invoke ReadFile, eax, ecx, 1, edx, 0 ; invoke ReadFile, handle, pBuffer, #bytes, pBytesRead, 0
.if !eax
print LastError$(), 13, 10 ; good to know if an error occurred
.endif
pop ecx ; get value from the second stack buffer
print str$(ecx), " bytes read", 13, 10
pop ebx ; get value from the first stack buffer
call CloseHandle ; the handle is still on the stack, so this is invoke CloseHandle, eax
print str$(ebx), " is the first byte"
exit
end start
MasmBasic version:
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
Let esi=FileRead$("\Masm32\examples\exampl05\hlldemo\fileio\fileio.exe")
Inkey "The first two bytes are [", Chr$(Cvi (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1023)(esi)), "]"
Exit
end start
Output: The first two bytes are [MZ]
here's another example
notice that i set the file pointer to 0
that is not a necessary step, as when you open a file, it is set to 0
but - if you want to read some other offset, the code is there
Thank's a lot guys:D
i wanted to mention....
the buffer only needs to be 1 byte long, in this case
i modified a program that i had previously written to create emu8086Read
it read the entire contents of the file into the buffer
I've tried to make what you have said in my code and it doesn't work,it works well separate reading from emu8086.io.
So i have a fan wich i must controll from emu8086 so i must write from emu in emu8086.io file and i must take the value and controll my fan.
The variable i must modify is named Buffer wich inittialy i defined 5 to show that the code works.
I've created a proc wich can read from file and when i'm calling it before i do things with my buffer variable,my fan image won't apear.
I have no ideea why it is doing like that because separate,the two programs works perfectly.
So i have commented the part where i have done the file reading proc and where i call it.
So al i must do is to read from emu8086.io and put the value in buffer variable.
Any ideeas?
Thanks in advance
i don't think you really want to open, read, close the file every 30 mS :icon_eek:
that's a little over 30 times per second
you could also have the "file" routine return an error condition
and - i would choose a more unique name for it :P
GetFileByte proc
;--------------------------------
;get file size
;--------------------------------
INVOKE GetFileAttr,offset szFileName
or eax,eax
jz Exit00
mov dwFileSize,eax
;--------------------------------
;open file
;--------------------------------
INVOKE OpnFile,offset szFileName,OPF_FILERANDOM
sub eax,INVALID_HANDLE_VALUE
jz Exit00
add eax,INVALID_HANDLE_VALUE
mov hFile,eax
;--------------------------------
;set file pointer (to 0)
;--------------------------------
INVOKE SetFilePointer,hFile,0,NULL,FILE_BEGIN
;--------------------------------
;read 1 byte into buffer
;--------------------------------
INVOKE ReadFile,hFile,offset Buffer,1,offset dwNumBytes,NULL
;--------------------------------
;close file
;--------------------------------
INVOKE CloseHandle,hFile
Exit00:
ret
GetFileByte endp
if the routine exits with EAX = 0, it means an error occured
I have done what you have said,i have modified the routine,it doesn't give me any error regarding eax.
The only problem is when i call the proc,the image dissapears.I don't have any errors.
I also tryied pushing eax,abx,acx because they are used after but it still doesn't work,need help!
Thanks
here's the question...
how often is the value in the file going to change ?
you are trying to read it 33 times per second
if you can read it once - then do that outside of the WM_TIMER code (WM_CREATE, perhaps)
if the file value is updated often, then you might take another approach
set up a counter (dword) variable (initial value = 1)
each time WM_TIMER is received, decrement the counter
when the counter reaches 0, read the file byte and reset the counter variable
now, how often it is updated depends on the timer elapse and the counter variable
i would think you could update once every minute or so
so, the counter variable might be reset to something like 2000
The value is changed often beause i controll the fan from emu 8086 so i can change the value after 2 seconds for example.
The thing is i'm knew in masm and i don't know how to work with a counter.
Can you help me please:)
I've also tried to only read it once,outside the counter and it hasn't worked
well - the value at offset 0 in your emu8086.io file is 0, if that tells you anything :P
i have another emu8086.io file here that is 201 bytes in size, and has 0C2h in the first byte
in the .DATA section
dwFileCounter dd 1
the first time WM_TIMER is received, it will cause an initial file read because 1 will become 0
in the WM_TIMER code
dec dwFileCounter
.if ZERO?
mov dwFileCounter,2000 ;with a 30 mS timer elapse, update once every minute
call GetFileByte
.if !eax
INVOKE Beep,800,100 ;beep at 800 Hz for 100 mS if error reading file
.endif
.endif
i updated the GetFileByte routine previously posted
these are the lines that changed
sub eax,INVALID_HANDLE_VALUE
jz Exit00
add eax,INVALID_HANDLE_VALUE
mov hFile,eax
Wasteful, Dave :eusa_naughty:
if INVALID_HANDLE_VALUE eq -1
inc eax
jz Exit00 ; 4 bytes
dec eax
else
sub eax, INVALID_HANDLE_VALUE
jz Exit00 ; 8 bytes
add eax, INVALID_HANDLE_VALUE
endif
I've done all you have said and made all the necesary changes that you told me,but when we put the call proc ,my image dissapears:(.
It's the same problem.There are no errors but if i let the call getfilebyte there my image won't apear.I'm stuck:(
Here is my program with the updates.In also modifyed my emu 8086 file,and the number at the first port is 155 now.
I don't have any ideeas what the problem can be:(
In my test, using your files, the problem was not the calls to GetFileByte but an endless loop in your WM_TIMER handler. Try enabling the calls to GetFileByte and commenting out the "jne et". I suggest you clean up your logic and your code. Before you go to the trouble of using a debugger to find the problem, you could try linking your app as a console app and adding code to display whatever you need to see on the console. I prefer to use the printf macro for this, for example:
CALL GetFileByte
pushad
printf("EAX:%d\n",eax)
popad
mov al,byte ptr Buffer
pushad
; printf expects 32 or 64-bit integers:
movzx eax, al
printf("AL:%d\n",eax)
popad
add com,1
pushad
movzx eax, com
printf("com:%d\n",eax)
popad
EAX:1
AL:155
com:2
also - you can speed up the GetFileByte process......
open the file in WM_CREATE code and store the handle
i like to use GetFileAttr to get the file size and verify the file exists - optional
if there is an error, MessageBox and exit with EAX = -1 to exit without creating the window
in the WM_TIMER code, SetFilePointer to 0 and use ReadFile to read 1 byte
in the WM_DESTROY handler, INVOKE CloseHandle,hFile
You were right,it worked because i used a while loop instead of comparing and jumping to et label.
The thing is that i don't understand why with jne doesn't work and with a while loop it worked?
I must mention that using both methods,the fan was doing exactly the same thing,but when the getfilebyte was called,with jne not commented my image was disapearing and when i used while loop,with the same code it worked.
I was only comparing com variable with al,a register in wich i put the buffer vaiable.I did this thing because cmp does not allow memory,memory,it can allow memory,registerso i've put it in al.
Then i was adding using FPU the number of times it was in Buffer,that was read from the file.
With the while loop i've done the same thing but i havn't used any jump,can you tell me why it happened like this?
THANKS
To know what is happening in the loop you need some way to monitor the values of the loop variables. By displaying the values of AL and com inside the loop I can see that the loop is running 155 times each time the timer fires with the call to GetFileByte enabled, and 7 times with the call to GetFileByte disabled. On each loop the value in xmm3 is being doubled. If I change the code to add 1.0 to the value in xmm3 on each loop, instead of doubling it:
add com,1
;addss xmm3,xmm3
.data
xxx REAL4 1.0
.code
addss xmm3,xxx
Then the fan displays OK with the call to GetFileByte enabled.
It is OK because I have defined my buffer at the begginig being 7 but the thing in using cmp com,al and jmp makes my image to disappear,obviously it s an endless loop but the code is the same when I m doing it with while and works , I m just doing while com<al and then the code is the same and I don't understantand why because my cmp , jump is making the same thing that while loop does
Knowing nothing about the code, but just reading the descriptions of the problem you have (works if using while but not with cmp jxx), I can only assume that your cmp jmp code is interpreting the results incorrectly, i.e., you are making a signed comparison and jumping on an assumed unsigned result, or you are making an unsigned comparison and jumping on an assumed signed result. Read the documentation about ja (jump if above - unsigned) and jg (jump if greater - signed).
Dave.
Hi,
As Dave says, you may have a wrong conditional jump. Put
.XLIST before including the INCLUDE files. And put a .LIST directive
after the include files, and generate a listing of both programs so
you can see what changes in teh generated code. You can put
the .XLIST and .LIST just around the code in question, if you think
that is easier.
Regards,
Steve N.