CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 17
  1. #1
    John E is offline Elite Member Power Poster
    Join Date
    Apr 2001
    Location
    Manchester, England
    Posts
    4,835

    Unhappy Can't seem to compile this with VC++

    I'm compiling a module that was originally written for the gcc compiler. It contains a few sections of x86 assembly language that look something like this:-

    Code:
    	asm  volatile (
    		"fxsave (%0)"
    		:
    		: "r" (fxbuf)
    		: "memory"
    	);
    The code builds fine with Cygwin gcc but MSVC++ doesn't seem to like it at all. Firstly, it doesn't seem to recognise the volatile keyword (or at least it doesn't like it being used with asm). But even if I comment that out, the rest of the code doesn't compile either. I don't know much about assmebly language but I think the colons might be screwing things up.

    Can anyone suggest how I could modify this to keep MSVC++ happy?
    "A problem well stated is a problem half solved.” - Charles F. Kettering

  2. #2
    Join Date
    May 1999
    Location
    ALABAMA, USA
    Posts
    9,917

    Re: Can't seem to compile this with VC++

    John, inline assembly is compiler specific and is not portable.
    I am not sure what did you comment out but asm keyword does not exist; it is AT&T C++ keyword. VS is using MASM assembly equivalent therefore you will have to stick to MASM rules so use __asm.

    I do not think VS compiler supports fxsave. I think you are trying to write some kind of floating point arithmetic’s routine. Are you sure that you have to use assembly?
    There are only 10 types of people in the world:
    Those who understand binary and those who do not.

  3. #3
    Join Date
    Jul 2002
    Posts
    2,543

    Re: Can't seem to compile this with VC++

    This code is compiled in VS2005, does not cause exceptions an blue screen:

    Code:
    int _tmain(int argc, _TCHAR* argv[])
    {
        char memory[512];
    
        __asm
        {
            fxsave memory
        };
    
        // do something ...
    
        __asm
        {
            fxrstor memory
        };
    
        return 0;
    }
    It saves the current state of the x87 FPU, MMX technology, XMM, and MXCSR registers
    to a 512-byte memory location, and then restores it from this memory. Possibly, original code writer has reasons to do this.

    See details in the Intel® 64 and IA-32 Architectures Software Developer's Manual
    Volume 2A: Instruction Set Reference, A-M, which can be downloaded from here:
    http://www.intel.com/products/processor/manuals/
    Direct download link:
    http://www.intel.com/Assets/PDF/manual/253666.pdf

  4. #4
    Join Date
    May 1999
    Location
    ALABAMA, USA
    Posts
    9,917

    Re: Can't seem to compile this with VC++

    As I already stated I hardly ever use inline assembly. Last time I used MASM was about 20 years ago still using it for DOS.
    Do you have any additional options/add-ins installed?
    fxsave/fxsave is not recognized in 2005 nor is it recognized in 2005.
    Is it part of the x86 family instructions set?
    There are only 10 types of people in the world:
    Those who understand binary and those who do not.

  5. #5
    Join Date
    Jun 2008
    Posts
    592

    Re: Can't seem to compile this with VC++

    [moving post from http://www.codeguru.com/forum/showthread.php?t=488642]

    I suppose you need to look up http://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html
    and look up what fxsave is suppose to do and convert it to vc++ inlined assembly.
    this is a subset of x86 which is called x87. http://siyobik.info/index.php?module=x86&id=128 http://en.wikipedia.org/wiki/X87
    0100 0111 0110 1111 0110 0100 0010 0000 0110 1001 0111 0011 0010 0000 0110 0110 0110 1111 0111 0010
    0110 0101 0111 0110 0110 0101 0111 0010 0010 0001 0010 0001 0000 0000 0000 0000
    0000 0000 0000 0000

  6. #6
    Join Date
    May 1999
    Location
    ALABAMA, USA
    Posts
    9,917

    Re: Can't seem to compile this with VC++

    Interesting. . .
    Thanks for the input.
    There are only 10 types of people in the world:
    Those who understand binary and those who do not.

  7. #7
    John E is offline Elite Member Power Poster
    Join Date
    Apr 2001
    Location
    Manchester, England
    Posts
    4,835

    Re: Can't seem to compile this with VC++

    Thanks for all the input guys. Apart from Alex's example it's quite difficult to find any examples of using these extensions for MASM. although I did find a few examples for translating AT&T instructions into MASM instructions. Fortunately though, I also come across a site called the MASM forum. If I can't figure this out myself, I might join that forum and see if anyone can help.
    "A problem well stated is a problem half solved.” - Charles F. Kettering

  8. #8
    Join Date
    Jul 2002
    Posts
    2,543

    Re: Can't seem to compile this with VC++

    C++ inline Assembly is not MASM, this is plain Assembly for Intel processors. Any valid Intel Assembly instructions must compile. The interesting point here why code author needs to use fxsave command. Maybe to restore processor state later with fxrstor command, in this case what does he do between these commands? Or to analyze memory region filled by this command. The answer is in the code you are working with. Understandinf this, maybe it is possible to find another way to complete the same task without Assembly.

  9. #9
    John E is offline Elite Member Power Poster
    Join Date
    Apr 2001
    Location
    Manchester, England
    Posts
    4,835

    Re: Can't seem to compile this with VC++

    Hmmm.... you've confused me now. The syntax is definitely AT&T syntax. I'd been assuming this was the reason why it wouldn't compile under Visual C++ (remember, the code was originally written to build under gcc).

    FYI the memory state doesn't get restored - but once it's in the buffer, the buffer contents get examined (a few lines later) and used to set a particular flag. The next few lines look like this:-

    Code:
    			uint32_t mxcsr_mask = *((uint32_t*) &fxbuf[28]);
    			
    			/* if the mask is zero, set its default value (from intel specs) */
    			
    			if (mxcsr_mask == 0) {
    				mxcsr_mask = 0xffbf;
    			}
    			
    			if (mxcsr_mask & (1<<6)) {
    				_flags = Flags (_flags | HasDenormalsAreZero);
    			} 
    
    			free (fxbuf);
    Last edited by John E; November 24th, 2009 at 03:11 AM.
    "A problem well stated is a problem half solved.” - Charles F. Kettering

  10. #10
    Join Date
    Jul 2002
    Posts
    2,543

    Re: Can't seem to compile this with VC++

    Code:
    char fxbuf[512];
    
    __asm
    {
        fxsave fxbuf
    }
    
    // use fxbuf
    I beleive this is quite enough to get the same functionality as in original code.
    In the Intel document pointed in my first post, you can find memory structure returned by fxsave command. This can help to understand what is the source of these flags.
    In VC++ 2005 this code is compiled. Posiibly some oldest VC version does not know this command, because it was developed when this command did not exis yet. What version do you use?
    Last edited by Alex F; November 24th, 2009 at 04:39 AM.

  11. #11
    John E is offline Elite Member Power Poster
    Join Date
    Apr 2001
    Location
    Manchester, England
    Posts
    4,835

    Re: Can't seem to compile this with VC++

    I'm using VC++2005 Express Alex. I'll try your suggestion later. Thanks.
    Last edited by John E; November 24th, 2009 at 04:34 AM.
    "A problem well stated is a problem half solved.” - Charles F. Kettering

  12. #12
    John E is offline Elite Member Power Poster
    Join Date
    Apr 2001
    Location
    Manchester, England
    Posts
    4,835

    Re: Can't seem to compile this with VC++

    Alex, if it's not too much trouble could you translate this for me from AT&T syntax into MASM syntax...?

    Code:
    	unsigned long cpuflags = 0;
    
    	asm volatile (
    		"mov $1, &#37;%eax\n"
    		"pushl %%ebx\n"
    		"cpuid\n"
    		"movl %%edx, %0\n"
    		"popl %%ebx\n"
    		: "=r" (cpuflags)
    		:
    		: "%eax", "%ecx", "%edx", "memory"
    	);
    I could probably figure out the instructions mov, pushl, popl etc. But I'm not sure what 'memory' is, or 'cpuid', or what exactly it's doing with cpuflags.

    [Edit...] After doing some research on the internet I realised that this line:-

    : "%eax", "%ecx", "%edx", "memory"
    is just a list of clobbered registers that tells gcc not to assume that these will remain intact. I couldn't find any mention of a clobbored register list in any of the examples for MASM so I assumed it wasn't relevant. Armed with this information I made a brave attempt at converting the code myself - but didn't get very far....

    Code:
    	__asm volatile {       // <-- MASM doesn't accept 'volatile' here
    		mov   eax, 1
    		pushl ebx      // <-- MASM didn't recognise 'pushl'
    		cpuid
    		movl  edx, 0   // <-- MASM didn't recognise 'movl'
    		popl  ebx      // <-- MASM didn't recognise 'popl'
    		// Do something here with 'cpuflags' that I don't understand
    	};
    Last edited by John E; December 3rd, 2009 at 12:46 AM.
    "A problem well stated is a problem half solved.” - Charles F. Kettering

  13. #13
    Join Date
    Jul 2002
    Posts
    2,543

    Re: Can't seem to compile this with VC++

    VC++ has CPUID sample which shows how to work with this command in inline Assembly. If you don't have this sample, download all VC++ samples from Microsoft. I hope you can find all answers there.
    If VC++ doesn't support volatile, just don't use it.
    I don't understand why are you talking about MASM. If you work with inline Assembly in C++, use Intel Manuals as reference, MASM is not relevant.
    VC++ samples can be downloaded here:
    http://www.microsoft.com/downloads/d...displaylang=en
    Fill free to ask me if CPUID sample doesn't solve your problems.

  14. #14
    John E is offline Elite Member Power Poster
    Join Date
    Apr 2001
    Location
    Manchester, England
    Posts
    4,835

    Re: Can't seem to compile this with VC++

    Thanks Alex but my problem isn't really to do with cpuid any more; it's with the other highlighted items - specifically:-

    1) I don't understand the line ': "=r" (cpuflags)' in the original code. I assume it must either be saving some values to cpuflags or maybe comparing a register with cpuflags but I don't know how to implement that line in Intel syntax.

    2) volatile - From what I've read on the internet, inline assembly code which doesn't produce (or appear to produce) an output will usually get optimised away to NOP by the underlying compiler. With gcc, volatile is used to prevent this optimization from happening. Maybe it's just not a problem with VC++ inline assembly? Or maybe some other technique should be used?

    3) I assumed that inline assembly in VC++ would just get passed to MASM but that mustn't be true from what you said. So my third problem is that the VC++ inline assembler doesn't recognise movl, popl, and pushl. That seems strange if they are valid processor instructions. I wondered if I might just have the syntax wrong. Or should I just use mov, pop and push?
    Last edited by John E; December 4th, 2009 at 03:36 AM.
    "A problem well stated is a problem half solved.” - Charles F. Kettering

  15. #15
    Join Date
    Jul 2002
    Posts
    2,543

    Re: Can't seem to compile this with VC++

    I didn't hear about Assembly optimization in C++. AFAIK, inline Assembly is executed as is, so don't care about volatile keyword.
    Don't use instructions with l in the end, it looks like defaul mov, push, pop are OK for these registers.
    I strongly recommend to read Intel CPUID instruction reference. You need to understand what is the meaning of this code. Here are some reference fragments:

    CPUID returns processor identification and feature information in the EAX, EBX, ECX,
    and EDX registers. The instruction’s output is dependent on the contents of the EAX
    register upon execution.
    Table 3-20. Information Returned by CPUID Instruction
    Initial EAX Value 01H
    Information Provided about the Processor
    EAX
    EBX
    ECX
    EDX
    Version Information: Type, Family, Model, and Stepping ID
    Bits 7-0: Brand Index
    Bits 15-8: CLFLUSH line size (Value ∗ 8 = cache line size in bytes)
    Bits 23-16: Maximum number of addressable IDs for logical processors
    in this physical package*.
    Bits 31-24: Initial APIC ID
    Feature Information (see Figure 3-7 and Table 3-23)
    Feature Information (see Figure 3-8 and Table 3-24)
    ...

    Looks like all this related to this code. If you cannot find somebody which can translate this to Intel Assembly, you need to do this yourself. I don't know this Assembly version. It looks like your code fragment should be:
    Code:
    __asm 
    {		
        mov   eax, 1
        push ebx
        cpuid
        mov  edx, 0
        pop  ebx
    };
    Read also this:
    http://www.microsoft.com/msj/0298/hood0298.aspx
    http://www.microsoft.com/msj/0698/hood0698.aspx

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured