flat assembler
Message board for the users of flat assembler.

Index > Macroinstructions > Surprises of stdcall

Author
Thread Post new topic Reply to topic
booter



Joined: 08 Dec 2006
Posts: 67
booter 15 Feb 2010, 10:05
Maybe it's well known and I just missed it, but I don't remember reading that in some cases stdcall changes edx, and it seems eax as well. In fact that means that when you pass parameters mixing eax, edx, and "addr" in one call it may produce unpredictable results, though digging deep into stdcall and pushd macro you can actually predict it.

Found in "pushd" macro after noticing edx changed by stdcall
Code:
    mov eax,dword [..address]
   lea edx,[..address]
    

Should it be considerd a bug?
At list this "errata" should be fully documented!

Most probably it's possible to detect this "side effect" in stdcall macro and wrap the call with push edx / pop edx. Unfortunately, I'm not good enough with macros to fix it quickly by myself.
Post 15 Feb 2010, 10:05
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20335
Location: In your JS exploiting you and your system
revolution 15 Feb 2010, 10:12
It has been mentioned before. IIRC, I even suggested a method (and gave the macros) to fix it but no one thought it needed fixing. But if not fixed it should be mentioned in the macro documentation.
Post 15 Feb 2010, 10:12
View user's profile Send private message Visit poster's website Reply with quote
Picnic



Joined: 05 May 2007
Posts: 1389
Location: Piraeus, Greece
Picnic 15 Feb 2010, 11:01
revolution wrote:
It has been mentioned before.
I seem to have missed that info, surprised to hear that but good to know Very Happy
Post 15 Feb 2010, 11:01
View user's profile Send private message Visit poster's website Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20335
Location: In your JS exploiting you and your system
revolution 15 Feb 2010, 13:18
Post 15 Feb 2010, 13:18
View user's profile Send private message Visit poster's website Reply with quote
booter



Joined: 08 Dec 2006
Posts: 67
booter 01 Mar 2010, 06:56
revolution wrote:
It has been mentioned before. IIRC, I even suggested a method (and gave the macros) to fix it but no one thought it needed fixing. But if not fixed it should be mentioned in the macro documentation.

A year passed since http://board.flatassembler.net/topic.php?t=8319, but the problem is still here. It's definitely not right to have FASM users to remember about this. I would say, it's extremely frustrating to deal with this "errata".
As a simple solution I propose just detect this problem in macros and raise an error to notify FASM user and allow him to change his code instead of spending hours looking for a bug in the program.
Tomasz, what do you think about this?

revolution, can you please write a macro to detect this? BTW, it may be even better solution because user can re-arrange his code and avoid inefficiensy and complexity related to your "automated" solution (I'm not critisizing your solution, just suggesting an alternative, please don't consider it offensive in any way).
Post 01 Mar 2010, 06:56
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20335
Location: In your JS exploiting you and your system
revolution 01 Mar 2010, 08:31
booter wrote:
A year passed since ...
Two years actually.
booter wrote:
revolution, can you please write a macro to detect this? BTW, it may be even better solution because user can re-arrange his code and avoid inefficiensy and complexity related to your "automated" solution ...
For a quick version you can just take the original macro and change the two lines that save and restore edx and replace with code to generate errors:
Code:
macro callpusher ret_arg_count,[arg] {
    common
     local edx_corrupted_flag, edx_save_flag, temp_edx_save_flag, arg_count, temp_arg_count, ip, opcode
  temp_arg_count=0
    reverse
     match x =edx y,:arg: \{
               if defined edx_corrupted_flag & edx_corrupted_flag=1
                    temp_edx_save_flag=1
                        edx_corrupted_flag=0
                        rb -1 ;error with use of edx!
               end if
      \}
    ip=$
        pushd arg
   load opcode from ip
 if opcode=0x8d
              edx_corrupted_flag=1
        end if
      temp_arg_count=temp_arg_count+1
    common
       if defined temp_edx_save_flag
               edx_save_flag=1
     end if
      arg_count=temp_arg_count
    ret_arg_count=arg_count
}    
Not tested though. And can probably be improved now that the edx saving code is not used.
Post 01 Mar 2010, 08:31
View user's profile Send private message Visit poster's website Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr 02 Mar 2010, 00:05
revolution,

What about two-pass approach? First pass pushes everything besides addr args (push any for them), then second pass use lea/mov [esp+X] to put EAs in their places (only for addrs, granted we have macro-expansion-time calculations). No need to bother with which register is corrupted.

The only problem is that addr is a part of pushd macro semantics, not stdcall/ccall/invoke/cinvoke.
Post 02 Mar 2010, 00:05
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20335
Location: In your JS exploiting you and your system
revolution 02 Mar 2010, 00:17
baldr wrote:
revolution,

What about two-pass approach? First pass pushes everything besides addr args (push any for them), then second pass use lea/mov [esp+X] to put EAs in their places (only for addrs, granted we have macro-expansion-time calculations). No need to bother with which register is corrupted.

The only problem is that addr is a part of pushd macro semantics, not stdcall/ccall/invoke/cinvoke.
There is another problem. What about this:
Code:
stdcall function, addr edx+8, addr ecx+8, addr edx+4, addr ecx+4    
Post 02 Mar 2010, 00:17
View user's profile Send private message Visit poster's website Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr 02 Mar 2010, 00:27
revolution,

Nobody's perfect. Indeed, many addrs are evil and should be banned to Void forever. Wink

Yet push/lea/xchg trick owns them all (though slowly). Wink
Post 02 Mar 2010, 00:27
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20335
Location: In your JS exploiting you and your system
revolution 02 Mar 2010, 00:29
I can be solved without xchg. I don't use xchg in my macros.
Post 02 Mar 2010, 00:29
View user's profile Send private message Visit poster's website Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr 02 Mar 2010, 00:36
revolution,

I know that it can be. fasm macro and interpretive facilities are powerful enough for that. I'll look into that, definitely.
Post 02 Mar 2010, 00:36
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.