none
mov instruction failing RRS feed

  • Question

  • I recently upgraded a C# project to Visual Studio 2010 and .NET Framework 4.0.  I'm seeing bizarre behaviour where a mov instruction in the disassembly appears to be writing the value to the wrong location.

    The project is running in debug compiled for Any CPU.

    The static class variable is a boolean and is declared as follows:

    		static bool bAreEnvironmentVariablesAlreadyInitialized = false;
    00000000 sub     rsp,28h 
    00000004 mov     rax,7FF00184528h 
    0000000e mov     eax,dword ptr [rax] 
    00000010 test    eax,eax 
    00000012 je     0000000000000019 
    00000014 call    FFFFFFFFEBC1A450 
    00000019 mov     byte ptr [00013B50h],0 
    
    

    The function does a test to see if the variable is initialised and if not executes code and sets it to true.

    The beginning of the if condition looks like:

    00000000 mov     dword ptr [rsp+8],ecx 
    00000004 push    rbx 
    00000005 sub     rsp,1D0h 
    0000000c xor     eax,eax 
    0000000e mov     qword ptr [rsp+70h],rax 
    00000013 mov     qword ptr [rsp+60h],rax 
    00000018 mov     qword ptr [rsp+58h],rax 
    0000001d mov     qword ptr [rsp+50h],rax 
    00000022 mov     qword ptr [rsp+48h],rax 
    00000027 mov     qword ptr [rsp+40h],rax 
    0000002c mov     qword ptr [rsp+38h],rax 
    00000031 mov     qword ptr [rsp+30h],rax 
    00000036 mov     qword ptr [rsp+28h],rax 
    0000003b mov     qword ptr [rsp+20h],rax 
    00000040 xor     eax,eax 
    00000042 mov     dword ptr [rsp+78h],eax 
    00000046 mov     byte ptr [rsp+68h],al 
    0000004a mov     rax,7FF00184528h 
    00000054 mov     eax,dword ptr [rax] 
    00000056 test    eax,eax 
    00000058 je     000000000000005F 
    0000005a call    FFFFFFFFEBC17270 
    0000005f nop 
    			if( !bAreEnvironmentVariablesAlreadyInitialized )
    00000060 mov     al,byte ptr [00010970h] 
    00000066 mov     byte ptr [rsp+68h],al 
    0000006a movzx    eax,byte ptr [rsp+68h] 
    0000006f test    eax,eax 
    00000071 jne     00000000000007E5 
    

    So you would expect the following instruction at the end of the if condition to work:

    				bAreEnvironmentVariablesAlreadyInitialized = true;
    000007dd mov     byte ptr [00010970h],1 
    
    

    However the value isn't being updated.

    If I move the assignment to just after the if condition, the value is updated correctly.  If I change the framework version back to 3.5 it works correctly.  If I insert the assignment of another static variable before this one (that is also used in the function) it fails to change value as well.

    While I have workarounds for this issue in particular, I'm more concerned about the general case where the code is behaving incorrectly.  I have tried creating a test project but it isn't reproducing the scenario yet.

    Tuesday, November 30, 2010 5:24 PM

Answers

  • Hi, a colleague reproduced the issue, its a little clearer with this code:

    static void Func2()

    {

        //if (!Initialised)

        while (!Initialised)

        {

            Regex VarRE = new Regex(@"(?<Variable>[^\=]*)=(?<Value>.+)", RegexOptions.IgnoreCase | RegexOptions.Compiled);

            string[] Data = new string[]

            {

                  "x=7",

                  "y=123"

           };

            foreach (string s in Data)

            {

                Match M = VarRE.Match(s);

                if (M.Success)

                {

                    Console.WriteLine("{0}={1}", M.Groups["Variable"].Value, M.Groups["Value"].Value);

                }

            }

     

            Initialised = true;

        }

    }

     

    which never falls out of the while loop.  

    you may want to report your issue on the connect web site as well.

    https://connect.microsoft.com/

    My suggestion is to see about what options to check out first, here is some info for more in depth

    level into the problems through support.

    There are various support options such as advisory and per issue. Please visit the below link to see

    the various paid

    support options that are available to better meet your needs.

    http://support.microsoft.com/default.aspx?id=fh;en-us;offerprophone

     


    bill boyce
    • Marked as answer by eryang Thursday, December 9, 2010 2:36 AM
    Monday, December 6, 2010 5:34 PM
    Moderator
  • Thank you, logged to: https://connect.microsoft.com/VisualStudio/feedback/details/628943/address-for-mov-instruction-no-longer-valid-in-net-framework-4-0-applications  I've used your example since the loop shows the incorrect behaviour much better.

    • Marked as answer by eryang Thursday, December 9, 2010 2:36 AM
    Monday, December 6, 2010 6:18 PM

All replies

  •  

    Hi,

     

    Thank you for your question. We're doing research on this issue. It might take some time before we get back to you.


    Sincerely,
    Eric
    MSDN Subscriber Support in Forum
    If you have any feedback of our support, please contact msdnmg@microsoft.com.
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    Wednesday, December 1, 2010 3:40 AM
  • I'll keep trying to get a repro but the basic case of:

    if( !x )
    {
      <stuff>
      x = true;
    }
    

    Doesn't trigger when <stuff> is the trivial case.

    Wednesday, December 1, 2010 4:04 AM
  • Have a repro using .NET 4.0, compiled for any cpu & debug:

    using System;
    using System.Collections.Generic;
    using System.Text.RegularExpressions;
    using System.Linq;
    using System.Text;
    
    namespace TestBool
    {
    	class Program
    	{
    		static void Main(string[] args)
    		{
    			Func2();
    		}
    
    		static bool Initialised = false;
    		
    		static void Func2()
    		{
    			if (!Initialised)
    			{
    				Regex VarRE = new Regex(@"(?<Variable>[^\=]*)=(?<Value>.+)", RegexOptions.IgnoreCase | RegexOptions.Compiled);
    				string[] Data = new string[] 
    				{
    					"x=7",
    					"y=123"
    				};
    				foreach (string s in Data)
    				{
    					Match M = VarRE.Match(s);
    					if (M.Success)
    					{
    						Console.WriteLine("{0}={1}", M.Groups["Variable"].Value, M.Groups["Value"].Value);
    					}
    				}
    
    				Initialised = true;
    			}
    		}
    	}
    }
    
    

     

     

     

    Wednesday, December 1, 2010 4:35 PM
  • Hi, a colleague reproduced the issue, its a little clearer with this code:

    static void Func2()

    {

        //if (!Initialised)

        while (!Initialised)

        {

            Regex VarRE = new Regex(@"(?<Variable>[^\=]*)=(?<Value>.+)", RegexOptions.IgnoreCase | RegexOptions.Compiled);

            string[] Data = new string[]

            {

                  "x=7",

                  "y=123"

           };

            foreach (string s in Data)

            {

                Match M = VarRE.Match(s);

                if (M.Success)

                {

                    Console.WriteLine("{0}={1}", M.Groups["Variable"].Value, M.Groups["Value"].Value);

                }

            }

     

            Initialised = true;

        }

    }

     

    which never falls out of the while loop.  

    you may want to report your issue on the connect web site as well.

    https://connect.microsoft.com/

    My suggestion is to see about what options to check out first, here is some info for more in depth

    level into the problems through support.

    There are various support options such as advisory and per issue. Please visit the below link to see

    the various paid

    support options that are available to better meet your needs.

    http://support.microsoft.com/default.aspx?id=fh;en-us;offerprophone

     


    bill boyce
    • Marked as answer by eryang Thursday, December 9, 2010 2:36 AM
    Monday, December 6, 2010 5:34 PM
    Moderator
  • Thank you, logged to: https://connect.microsoft.com/VisualStudio/feedback/details/628943/address-for-mov-instruction-no-longer-valid-in-net-framework-4-0-applications  I've used your example since the loop shows the incorrect behaviour much better.

    • Marked as answer by eryang Thursday, December 9, 2010 2:36 AM
    Monday, December 6, 2010 6:18 PM