The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: Ani_Skywalker on October 31, 2011, 05:36:49 PM

Title: fread or readfile?
Post by: Ani_Skywalker on October 31, 2011, 05:36:49 PM
What is the difference between these two? I assume ReadFile is a call to the Win 32 API function with the same name? Is fread the equivalent of a macro that calls ReadFile in the end? I can't find the include-files where fread is defined. Where should I search for it?

Also, here is my code, it works but you guys can probably see bad standards in it. Feel free to let me know about it.

include \masm32\include\masm32rt.inc ; All includes needed for comon MASM32-programming

.code
start:

call main
inkey ; Wait for input to close console
exit

main proc
local hFile :HANDLE
local count :DWORD
local buffer :PTR BYTE

mov hFile, fopen("008.dat")
mov count, fread(hFile, addr buffer, 1001)
fclose hFile
ret
main endp


end start


Title: Re: fread or readfile?
Post by: jj2007 on October 31, 2011, 05:41:19 PM
\masm32\macros\macros.asm:
  ; ------------------------------------------------
  ; read data from an open file into a memory buffer
  ; ------------------------------------------------
    fread MACRO hFile,buffer,bcnt
      LOCAL var
      .data?
        var dd ?
      .code
      invoke ReadFile,hFile,buffer,bcnt,ADDR var,NULL
      mov eax, var
      EXITM <eax>       ;; return bytes read
    ENDM


It is actually not the most efficient code, as it needs a global variable. Here is an alternative:
push eax ; create a slot for bytes read
mov eax, esp
invoke ReadFile, hFile, lpBuffer, bytes, eax, 0
pop eax ; bytes read
Title: Re: fread or readfile?
Post by: ToutEnMasm on October 31, 2011, 06:01:04 PM
Masm use macro.
When you don't know if it is a macro  or a function proceed as follow.
Put    .NOLIST a the start of your source
Before the instruction you want to know:
         .LISTALL
Just after the instruction you want to know:
         .NOLIST
Made a listing.
and in the listing ,if it is a macro ,you see his code expanded as this
Quote

            .NOLIST
               .LISTALL
                  SET_CRT_DEBUG_FIELD _CRTDBG_LEAK_CHECK_DF   
000002ED  6A FF      *       push    -000000001h
000002EF  E8 00000000 E   *       call   _CrtSetDbgFlag
000002F4  83 C4 04      *       add    esp, 000000004h
              1      invoke _CrtSetDbgFlag,_CRTDBG_REPORT_FLAG
              1      ;Returns the previous state of _crtDbgFlag
000002F7  83 C8 20        1      or eax,_CRTDBG_LEAK_CHECK_DF
000002FA  50         *       push   eax
000002FB  E8 00000000 E   *       call   _CrtSetDbgFlag
00000300  83 C4 04      *       add    esp, 000000004h
              1      invoke _CrtSetDbgFlag,eax
               .NOLIST


Title: Re: fread or readfile?
Post by: dedndave on October 31, 2011, 07:22:07 PM
push eax ; create a slot for bytes read
mov eax, esp
invoke ReadFile, hFile, lpBuffer, bytes, eax, 0
pop eax ; bytes read


Jochen, better if you return the count in ECX
EAX holds the status   :U

another way to go...
push eax ; create a slot for bytes read
mov eax, esp
invoke ReadFile, hFile, lpBuffer, bytes, eax, 0
pop ecx ; bytes read
cmp ecx,bytes

now, the macro returns with ZF set if bytes requested = bytes read
and, EAX has the return status
Title: Re: fread or readfile?
Post by: Ani_Skywalker on October 31, 2011, 07:50:25 PM
Now, pretend I prefer to call ReadFile directly, like this:

mov hFile, fopen("fread-readfile.dat")
push 0
push 81
push ptr$(lpBuffer)
push hFile


Wouldn't it be faster? This compiles, but gives some kind of error in runtime, the error looks to be memory-related?
Title: Re: fread or readfile?
Post by: dedndave on October 31, 2011, 07:55:48 PM
the small differences in speed are minimal compared to the time consumed by the ReadFile call
macros are handy - they can save you some typing
however, when you are learning how things work, they hide a lot of stuff
Title: Re: fread or readfile?
Post by: Ani_Skywalker on October 31, 2011, 07:58:04 PM
Dave: Yeah, that is one of the reasons I refuse to use macros. Got it to work by the way, had forgot one parameter when calling. But bellow code both compiles and runs without error.

mov hFile, fopen("fread-readfile.dat")
push 0
push bytesRead
push ptr$(lpBuffer)
push 81
push hFile
call ReadFile
Title: Re: fread or readfile?
Post by: dedndave on October 31, 2011, 08:19:17 PM
i noticed that, in your original post, you allocated 1 byte for the buffer   :P
        INCLUDE \masm32\include\masm32rt.inc

;----------------------------------------------------------

BYTES_TO_READ EQU 1001
BUFFER_SIZE   EQU 1024

;----------------------------------------------------------

        .DATA

szFileName db '008.dat',0

szErrOpen  db 'Error Opening File',13,10,0
szErrRead  db 'Error Reading File',13,10,0
szSuccess  db 'Read File Successful',13,10,0

;----------------------------------------------------------

        .CODE

main    PROC

        LOCAL   hFile:HANDLE
        LOCAL   Count:DWORD
        LOCAL   Buffer[BUFFER_SIZE]:BYTE

        INVOKE  CreateFile,offset szFileName,GENERIC_READ,FILE_SHARE_READ,
                NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL
        mov     edx,offset szErrOpen
        or      eax,eax
        jz      Report2

        mov     hFile,eax
        INVOKE  ReadFile,eax,addr Buffer,BYTES_TO_READ,addr Count,NULL
        mov     edx,offset szErrRead
        or      eax,eax
        jz      Report1

        mov     edx,offset szSuccess

Report1:
        push    edx
        INVOKE  CloseHandle,hFile
        pop     edx

Report2:
        print   edx
        ret

main    ENDP

;----------------------------------------------------------

Start:  call    main
        inkey
        exit

;----------------------------------------------------------

        END     Start
Title: Re: fread or readfile?
Post by: jj2007 on October 31, 2011, 08:21:25 PM
Quote from: dedndave on October 31, 2011, 07:22:07 PM
Jochen, better if you return the count in ECX
EAX holds the status   :U
Yes, but the status is pretty useless:
QuotelpNumberOfBytesRead
Points to the number of bytes read. ReadFile sets this value to zero before doing any work or error checking
Comparing NumberOfBytesRead to zero or to the requested count is therefore a safer way to check for errors.
Title: Re: fread or readfile?
Post by: jj2007 on October 31, 2011, 08:23:18 PM
Quote from: Ani_Skywalker on October 31, 2011, 07:58:04 PM
      push 0         
      push bytesRead   <<<<<<<<< sure?
      push ptr$(lpBuffer)  <<<<<<<<< attention dangerous macro!
      push 81
      push hFile   
      call ReadFile
Title: Re: fread or readfile?
Post by: Ani_Skywalker on October 31, 2011, 10:25:12 PM
Quote from: jj2007 on October 31, 2011, 08:23:18 PM
      push 0         
      push bytesRead   <<<<<<<<< sure?
      push ptr$(lpBuffer)  <<<<<<<<< attention dangerous macro!
      push 81
      push hFile   
      call ReadFile

Well, not sure, but I use an uninitialized variable, should be almost as good as setting it to zero, or? The docs suggest zero though: http://msdn.microsoft.com/en-us/library/windows/desktop/aa365467%28v=vs.85%29.aspx

Ah, why is it a dangerous macro and how can I turn that line to pure assembly?
Title: Re: fread or readfile?
Post by: jj2007 on October 31, 2011, 10:35:09 PM
Quote from: Ani_Skywalker on October 31, 2011, 10:25:12 PM
Quote from: jj2007 on October 31, 2011, 08:23:18 PM
      push 0         
      push bytesRead   <<<<<<<<< sure?
      push ptr$(lpBuffer)  <<<<<<<<< attention dangerous macro!
      push 81
      push hFile   
      call ReadFile

Well, not sure, but I use an uninitialized variable, should be almost as good as setting it to zero, or? The docs suggest zero though: http://msdn.microsoft.com/en-us/library/windows/desktop/aa365467%28v=vs.85%29.aspx

Check the order of your paras. The doc uses the invoke order, you are pushing, so you must invert everything.

Quote
Ah, why is it a dangerous macro and how can I turn that line to pure assembly?

Just pulling your leg... but you better check what the macro does.
Title: Re: fread or readfile?
Post by: Gunner on October 31, 2011, 10:38:25 PM
Look at the file macros.asm in your masm32\macros directory to see the code of all the macros and how they are done :)
Title: Re: fread or readfile?
Post by: qWord on October 31, 2011, 10:39:52 PM
local buffer[1024]:BYTE
local bytesRead:DWORD
...
push 0
lea eax,bytesRead
push eax
push SIZEOF buffer
lea eax,buffer
push eax
push hFile
call ...
Title: Re: fread or readfile?
Post by: Ani_Skywalker on October 31, 2011, 10:44:51 PM
Quote from: jj2007 on October 31, 2011, 10:35:09 PM
Check the order of your paras. The doc uses the invoke order, you are pushing, so you must invert everything.

But isn't that exactly what I am doing? I push the first parameter last, the second to first second to last, and so on? Then when the cpu reads it from the stack it should come in reverse order, meaning the first one comes first etc. Or have I got it wrong?
Title: Re: fread or readfile?
Post by: Gunner on October 31, 2011, 10:50:20 PM
QuoteBOOL ReadFile(
  HANDLE hFile,
  LPVOID lpBuffer,
  DWORD nNumberOfBytesToRead,
  LPDWORD lpNumberOfBytesRead,
  LPOVERLAPPED lpOverlapped
);

so it would be:
push lpOverlapped
push lpNumberOfBytesRead
push nNumberOfBytesToRead
push lpBuffer
push hFile
call ReadFile


Of course you have to push the address of buffers were needed
Title: Re: fread or readfile?
Post by: Ani_Skywalker on October 31, 2011, 10:56:47 PM
Quote from: Gunner on October 31, 2011, 10:50:20 PM
so it would be:
push lpOverlapped
push lpNumberOfBytesRead
push nNumberOfBytesToRead
push lpBuffer
push hFile
call ReadFile


Which is what I am doing, right?
Title: Re: fread or readfile?
Post by: Ani_Skywalker on October 31, 2011, 11:50:24 PM
Quote from: qWord on October 31, 2011, 10:39:52 PM
local buffer[1024]:BYTE
local bytesRead:DWORD
...
push 0
lea eax,bytesRead
push eax
push SIZEOF buffer
lea eax,buffer
push eax
push hFile
call ...


qWord: As always, interesting posts. I have 2 questions about it:

1. Why do we need to load effective address before push, isn't enough that the value is poped upon call?
2. I understand it as (right or wrong) that we can use mov instead of lea? Which one is preferable? Which one uses least clock cycles?

I never seem to find where to look for clock cycles in Intel Software Developers Manual. Looking at page 649 in the pdf, I find lea explained, but nothing about clock cycles..
Title: Re: fread or readfile?
Post by: Gunner on October 31, 2011, 11:58:54 PM
Your beginning right?  Stop trying to save clock cycles...

You use lea because the buffer is local, and ReadFile needs an address.  Now if the buffer was global you CAN'T just push the variable (you would be pushing the value) you would have to push offset variable
Title: Re: fread or readfile?
Post by: Ani_Skywalker on November 01, 2011, 12:02:16 AM
Quote from: Gunner on October 31, 2011, 11:58:54 PM
Your beginning right?  Stop trying to save clock cycles...

Yes but I disagree with you here. If you learn something wrong to start with, it's just even harder to get it right the second time. Relearning is much harder then learning. I'll rather have a very slow start and take my time then start coding windows frames using invokes and the Win 32 api. That kind of programming is what I have C and Java for :)

Thanks for the answer though, appreciated!
Title: Re: fread or readfile?
Post by: jj2007 on November 01, 2011, 12:10:23 AM
Quote from: Ani_Skywalker on October 31, 2011, 10:56:47 PM
Quote from: Gunner on October 31, 2011, 10:50:20 PM
so it would be:
push lpOverlapped
push lpNumberOfBytesRead
push nNumberOfBytesToRead
push lpBuffer
push hFile
call ReadFile


Which is what I am doing, right?

No. What you are doing is as follows:

Quote from: Ani_Skywalker on October 31, 2011, 07:58:04 PM
Dave: Yeah, that is one of the reasons I refuse to use macros. Got it to work by the way, had forgot one parameter when calling. But bellow code both compiles and runs without error.

mov hFile, fopen("fread-readfile.dat")
push 0 ; lpOverlapped
push bytesRead   ;lpNumberOfBytesRead, i.e.LONG POINTER TO ...
push ptr$(lpBuffer)   ; should be nNumberOfBytesToRead, i.e. the numberof bytes
push 81     ; should be lpBuffer, i.e LONG POINTER TO ...
push hFile   ; that one is correct.
call ReadFile

Title: Re: fread or readfile?
Post by: awais_x on November 01, 2011, 01:03:17 AM
Amazing and nice looking site please love it and make more effective.. keep it up baby..

URL removed.

We do not allow this forum to be used for advertising.
Title: Re: fread or readfile?
Post by: qWord on November 01, 2011, 01:47:07 AM
Quote from: Ani_Skywalker on October 31, 2011, 11:50:24 PM1. Why do we need to load effective address before push, isn't enough that the value is poped upon call?
2. I understand it as (right or wrong) that we can use mov instead of lea?
1. if the address is unknown at compile time (local -> ebp-relative -> esp-relative), you must calculate it at runtime - LEA can do this.
2. only if not referencing a local variable
(Also, to make it clear: LEA is an arithmetic instruction, which never access any memory)
Title: Re: fread or readfile?
Post by: NoCforMe on November 01, 2011, 03:12:19 AM
Quote from: Ani_Skywalker on November 01, 2011, 12:02:16 AM
I'll rather have a very slow start and take my time then start coding windows frames using invokes and the Win 32 api. That kind of programming is what I have C and Java for :)

Like you, I'm something of a n00b to Windows assembly-language programming (though I've been writing DOS-based '86 assembly for a long time). I think you may have a somewhat distorted picture of what INVOKE does.

When I started Win32 asm just a couple months ago, I had never used INVOKE, just plain CALLs. I would recommend to you that you use it. Why?

First of all, it incurs absolutely no more overhead than what you're doing when you push parameters "by hand". That's basically all it does, apart from some extra code that may occasionally be generated to move static addresses into a register (EAX) and then pushing the register. So all in all, it's pretty benign. It's not doing a lot of stuff "behind the curtain." In any case, I would also recommend that you code the two methods (pushing by hand vs. INVOKE) and look at the generated code in the listing file to see exactly what's being generated.

The reason I like to use INVOKE is that it makes it a hell of a lot easier to keep all those pesky parameters straight, especially for functions like CreateWindowEx() that take a lot of them. I HATE trying to chase down crap like [ESP + xxx]; honestly, it makes my head hurt, and I don't code well with headaches. Spend less time trying to be a macho "down-to-the-bare-metal" assembly programmer, and you'll have more energy to devote to debugging the damn program and dreaming up new stuff. It's hard enough to keep track of stuff as it is; why make it harder?

You'll still get very slick, streamlined, slim and fast code out of it, even if you let the assembler help you now and then. Myself, I draw the line at macros (I only use ones I invent myself) and the .if-.else-.endif constructs. Hell, if I wanted to code like that, why not just use C++?
Title: Re: fread or readfile?
Post by: ToutEnMasm on November 01, 2011, 05:47:41 AM

I see that the no use of invoke generate only questions and problems.Thinks are simple using:
Quote
      INVOKE     ReadFile, hFile,addr Buff, NumberOfBytesToRead,\
            addr NumberOfBytesRead ,0            
and what happen with the no use of invoke if you made a mistake ?
Invoke verify (at compile time) if the size of the parameter is correct and if the number of parameters is correct.
Use the push method at your own risks.


Title: Re: fread or readfile?
Post by: dedndave on November 01, 2011, 07:25:12 AM
there are times when using PUSH/CALL is advantageous
in certain cases, i may want to push values while they are in register for a call later
or - there may be times when i want to perform calculations or call other functions between parameter pushes
one example is if some of the parameters are in a table, and i want to use LODSD to get them
these are somewhat advanced tecniques, as they require extreme vigilance over the stack and, perhaps, registers

otherwise, use INVOKE   :U
not only does INVOKE check the parm count for you, but it is easier to read and maintain
Title: Re: fread or readfile?
Post by: dedndave on November 01, 2011, 08:38:19 AM
Ob1 Cannoli: "Become one with The Stack, my young padawan learner"

(http://www.masm32.com/board/index.php?action=dlattach;topic=17652.0;id=9901)
Title: Re: fread or readfile?
Post by: Ani_Skywalker on November 01, 2011, 11:56:37 AM
Quote from: NoCforMe on November 01, 2011, 03:12:19 AM
It's hard enough to keep track of stuff as it is; why make it harder?

Let's take this discussion once and for all :)

Answer to your question is: Because I like the learn->understand->do chain better then the learn->do chain.

Look at my original post in this thread, I used fread to read a file instead of the native ReadFile. After that it took almost 2.5 pages on this forum to sort out all questions about push/call operations. If I was about to code something useful in assembly, you probably would be right. At the moment, I'm just solving Project Euler problems to l-e-a-r-n.

Also, it has never been about being a "macho" guy. I ask noobish questions on open forums and show my lack off knowledge, hoping more experienced people have the time and willing to share their knowledge with me so I can learn and improve - that's the exact opposite of being "macho".

That said, I appreciate that shared your experience of the MASM-macros from an assembly programmers point of view.
Title: Re: fread or readfile?
Post by: dedndave on November 01, 2011, 02:26:06 PM
well - a lot of it has to do with personal choice

my choice - if it isn't speed critical, make it small
but then, programming is not my business
i am not worried about someone else maintaining my code

many of the professional programmers look at it this way:
if it isn't speed critical, make it as clear and readable as practical (maintainable)

there are other choices, as well
macros - how often - when
basically, i use macros for something quick - or to debug code
otherwise, i prefer to write my own stuff   :P

i also do not like indented lines or if/else/elseif/endif structures

it is all a matter of personal choice
each of us will defend our choices to the death   :lol
Title: Re: fread or readfile?
Post by: NoCforMe on November 02, 2011, 02:30:14 AM
Quote from: Ani_Skywalker on November 01, 2011, 11:56:37 AM
Quote from: NoCforMe on November 01, 2011, 03:12:19 AM
It's hard enough to keep track of stuff as it is; why make it harder?

Let's take this discussion once and for all :)

Answer to your question is: Because I like the learn->understand->do chain better then the learn->do chain.

Look at my original post in this thread, I used fread to read a file instead of the native ReadFile. After that it took almost 2.5 pages on this forum to sort out all questions about push/call operations. If I was about to code something useful in assembly, you probably would be right. At the moment, I'm just solving Project Euler problems to l-e-a-r-n.

Also, it has never been about being a "macho" guy. I ask noobish questions on open forums and show my lack off knowledge, hoping more experienced people have the time and willing to share their knowledge with me so I can learn and improve - that's the exact opposite of being "macho".

That said, I appreciate that shared your experience of the MASM-macros from an assembly programmers point of view.

Whoa just a second there, pardner. I meant no disrespect to you. Your point about learning is well taken. It's good go know what's actually going on in your code, which is why I suggested looking at the assembler listing if you do use INVOKE.

And  I certainly wasn't accusing you of macho programming. There are those who practice it, and I just wanted to warn you of that tendency, is all.

Good luck with your programming learning. Once you get over the hump you should be able to have fun with it.
Title: Re: fread or readfile?
Post by: Ani_Skywalker on November 02, 2011, 02:40:13 AM
Oh, I didn't take it as an insult. The reason why I gave such a long answer is that several people suggested similar approaches to me here, so I just wanted to sort out why I am asking all this dumb questions right now (besides the obvious fact that I am a noob) :)

And like I wrote, I appreciated your post. Thanks once again!