CodeGuru Forums -
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic Newsletters VB Forums Developer.com


Newest CodeGuru.com Articles:

  • Installing SQL Server 2008
  • Writing UDFs for Firebird Embedded SQL Server
  • [Updated] Shutdown Manager
  • Building Windows Azure Cloud Service Applications with Azure Storage and the Azure SDK

  • Search CodeGuru:
     



    Go Back   CodeGuru Forums > Other Programming > Assembly
    FAQ Members List Calendar Search Today's Posts Mark Forums Read

    Assembly Questions and Answers for Assembly here!

    Reply
     
    Thread Tools Search this Thread Rate Thread Display Modes
      #1    
    Old May 2nd, 2005, 05:06 PM
    Psytherium Psytherium is offline
    Member
     
    Join Date: Sep 2004
    Posts: 57
    Psytherium is an unknown quantity at this point (<10)
    Having a problem with inline assembly and calling conventions

    I'm working on an assignment that creates a function using inline assembly to compute the value of an expression. The following is the signature of the function.

    Code:
    long evaluate(char *code, bool trace);
    The expression pointed to by the code parameter computes a signed 32-bit value using a simple expression language. Each expression contains three fields. The first field is required but the other two vary in size depending on the value of the first field. The memory layout is shown below.

    Expression encoding:
    1-byte op-code | optional left operand bytes | optional right operand bytes

    Op-codes include three fields as shown below.

    Bits Description
    7-6 Operation code
    5-3 Left operand value
    2-0 Right operand value

    The operation code indicates how the operands will be transformed into the final resulting expression value.

    Code Operation
    00 minimum of left and right operand
    01 maximum of left and right operand
    10 sum of left and right operands
    11 difference between left and right operands (left-right)

    Each operation requires two operands (left and right). The value of each operand is given in the table below.

    Code Value of the operand
    000 constant 0
    001 constant 1
    010 constant 2
    011 constant 4
    100 1-byte signed value
    101 2-byte signed value
    110 4-byte signed value
    111 an expression (as defined here) (We'll ignore this one).

    Constants require no additional bytes. One-, two-, and four-byte values require the appropriate number of bytes.

    Here are some example inputs and what the output should be.

    Input | Output
    00 | min(0,0) = 0
    4A | max(1,2) = 2
    9C 7F | 4 + 127 = 131


    The following is my code. It compiles without any errors, but when i run it it just crashes.

    Code:
    //add2.cpp
    
    long __declspec(naked) evaluate(const char *code, bool trace)
    {
        _asm{
            push ebp
            mov esp, ebp
            push dword ptr [ebp+8]
            push code
            
            call eval
            
            add esp, 12
    		ret
            
        eval:
            mov eax, 0
    		mov ebx, 0
            mov ecx, 0
            mov edx, 0
    		mov esi, [ebp+8]
            mov ebx, [esi] 
            mov dl, [esi]
            and dl, 56
            shr dl, 3
            cmp dl, 7
            jne notexp
                  
        nextthreebits:
            cmp ecx, 1
            je op
            mov dl, [ebx]
            and dl, 7			;00000111
            cmp dl, 7
            mov ecx,1			;checked nextthreebits
            jne notexp
            
            jp op
            
        notexp:
            cmp dl, 4			;00000100 (check to see if byte value)
            jge signedvalue
            cmp dl, 3			;00000011 (check to see if const 4)
            je constant4
            and edx, 255		;11111111
    		push edx
            jp nextthreebits
            
         constant4:
            push 4
            jp nextthreebits    
        
        signedvalue:
            add dl, 4
            cmp dl, 0
            je onebyte
            cmp dl, 1
            je twobyte
            and edx, 255
            push edx
            add esi, 4
            jp nextthreebits
            
        onebyte:
            inc esi
            mov dl, [esi]
            and edx, 255
            push edx
            jp nextthreebits
            
        twobyte:
            inc esi
            mov dx, [esi]
            and edx, 255
            push edx
            add esi, 2
            jp nextthreebits
            
       
        op:
            mov dl, [ebx]
            and dl, 192			;11000000
            cmp dl, 0
            je min
            cmp dl, 64			;01000000
            je max
    		cmp dl,	128			;10000000
    		je sum
    		cmp dl, 192			;11000000
    		je subtract
    		jp done
            
        min:
            pop ebx				; right value
    		pop eax				; left value
            cmp ebx,eax			; right-left
            jle right
            jp done
            
        right:
            mov eax, ebx
            jp done
            
        max:
            pop ebx
    		pop eax
            cmp ebx,eax
            jg right
            jp done
                     
    	sum:
    		pop ebx
    		pop eax
    		add eax, ebx
    		jp done
    
    	subtract:
    		pop ebx
    		pop eax
    		sub eax, ebx
    		jp done
            
        recursive:          
            jp done
            
    	done:
            }
    }
    Here is the test file.

    Code:
    //testeval.cpp
    
    #include <stdio.h>
    #include <assert.h>
    
    long evaluate(const char *code, bool traceFlag);
    
    int main()
    {
        static const char test1[] = { 10 };
        static const char test2[] = { 0x4A };
        static const char test3[] = { 0x9C, 0x7F };
    
        long x = evaluate(test1,true);
        printf("test1 result %d\n\n",x);
      
        x = evaluate(test2,true);
        printf("test2 result %d\n\n",x);
        
        x = evaluate(test3,true);
        printf("test3 result %d\n\n",x);
    
    	return 0;
    }
    Any help would be GREATLY appreciated. I need help on this ASAP. I don't necessarily need the code revised for me(though that would be excellent) but atleast just some help on where I'm going wrong or which parts in the code i need to look at, etc. Thanks!
    Reply With Quote
      #2    
    Old May 8th, 2005, 02:34 AM
    SpinningVertex SpinningVertex is offline
    Junior Member
     
    Join Date: May 2005
    Posts: 6
    SpinningVertex is on a distinguished road (10+)
    Re: Having a problem with inline assembly and calling conventions

    I'm afraid I can't give you any exact instructions for a solution. But since it crashes, we can assume that you either cause an access violation or that you do not preserve the registers well enough for C so that the your thread starts trying to run code at some random place in the memory.

    If the later is the case, it can easily be fixed by adding PushAd (Which pushes All general purpos registers to the stack) at the start of your asm and PopAd(which pops them all) before "ret".

    If it still crashes after that,.. then you probably have an access violation. I usually make those when I treat a pointer as a value or the otherway around.

    Oh, and try to avoid using the registers directly, if your compiler translates the parameters and result names to registers when compiling. It makes it a bit easier to keep track of all the variables.

    Sorry if this isn't much help but it is all I can think of at the moment.

    Hope it turns out well!
    Reply With Quote
    Reply

    Bookmarks
    Go Back   CodeGuru Forums > Other Programming > Assembly


    Thread Tools Search this Thread
    Search this Thread:

    Advanced Search
    Display Modes Rate This Thread
    Rate This Thread:

    Posting Rules
    You may not post new threads
    You may not post replies
    You may not post attachments
    You may not edit your posts

    BB code is On
    Smilies are On
    [IMG] code is On
    HTML code is Off
    Forum Jump


    All times are GMT -5. The time now is 07:26 PM.



    Acceptable Use Policy

    internet.comMediabistrojusttechjobs.comGraphics.com

    WebMediaBrands Corporate Info


    Advertise | Newsletters | Feedback | Submit News

    Legal Notices | Licensing | Permissions | Privacy Policy


    Powered by vBulletin® Version 3.7.3
    Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
    Copyright WebMediaBrands Inc. 2002-2009