CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 2 of 2

Thread: A ".S" file

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

    A ".S" file

    I'm trying to build libffi using VC++. Apparently, this is possible (albeit from a command line) but only if I first install Cygwin, MSYS and MinGW.

    If all else fails I suppose I'll have to install them but I'd prefer to create a vcproj if possible. I created a suitable project and as it happened, I only encountered one module that won't compile. Unusually, the module is called win32.S and looks something like this:-

    Code:
    #define LIBFFI_ASM
    #include <fficonfig.h>
    #include <ffi.h>
    
    #ifdef _MSC_VER
    
    .386
    .MODEL FLAT, C
    
    EXTRN ffi_closure_SYSV_inner:NEAR
    
    _TEXT SEGMENT
    
    ffi_call_win32 PROC NEAR,
        ffi_prep_args : NEAR PTR DWORD,
        ecif          : NEAR PTR DWORD,
        cif_abi       : DWORD,
        cif_bytes     : DWORD,
        cif_flags     : DWORD,
        rvalue        : NEAR PTR DWORD,
        fn            : NEAR PTR DWORD
    
            ;; Make room for all of the new args.
            mov  ecx, cif_bytes
            sub  esp, ecx
    
            mov  eax, esp
    
            ;; Place all of the ffi_prep_args in position
            push ecif
            push eax
            call ffi_prep_args
    
            ;; Return stack to previous state and call the function
            add  esp, 8
    
    	;; Handle thiscall and fastcall
    	cmp cif_abi, 3 ;; FFI_THISCALL
    	jz do_thiscall
    	cmp cif_abi, 4 ;; FFI_FASTCALL
    	jnz do_stdcall
    	mov ecx, DWORD PTR [esp]
    	mov edx, DWORD PTR [esp+4]
    	add esp, 8
    	jmp do_stdcall
    do_thiscall:
    	mov ecx, DWORD PTR [esp]
    	add esp, 4
    do_stdcall:
            call fn
    
            ;; cdecl:   we restore esp in the epilogue, so there's no need to
            ;;          remove the space we pushed for the args.
            ;; stdcall: the callee has already cleaned the stack.
    
            ;; Load ecx with the return type code
            mov  ecx, cif_flags
    
            ;; If the return value pointer is NULL, assume no return value.
            cmp  rvalue, 0
            jne  ca_jumptable
    
            ;; Even if there is no space for the return value, we are
            ;; obliged to handle floating-point values.
            cmp  ecx, FFI_TYPE_FLOAT
            jne  ca_epilogue
            fstp st(0)
    
            jmp  ca_epilogue
    
    ca_jumptable:
            jmp  [ca_jumpdata + 4 * ecx]
    ca_jumpdata:
            ;; Do not insert anything here between label and jump table.
            dd offset ca_epilogue       ;; FFI_TYPE_VOID
            dd offset ca_retint         ;; FFI_TYPE_INT
            dd offset ca_retfloat       ;; FFI_TYPE_FLOAT
            dd offset ca_retdouble      ;; FFI_TYPE_DOUBLE
            dd offset ca_retlongdouble  ;; FFI_TYPE_LONGDOUBLE
            dd offset ca_retint8        ;; FFI_TYPE_UINT8
            dd offset ca_retint8        ;; FFI_TYPE_SINT8
            dd offset ca_retint16       ;; FFI_TYPE_UINT16
            dd offset ca_retint16       ;; FFI_TYPE_SINT16
            dd offset ca_retint         ;; FFI_TYPE_UINT32
            dd offset ca_retint         ;; FFI_TYPE_SINT32
            dd offset ca_retint64       ;; FFI_TYPE_UINT64
            dd offset ca_retint64       ;; FFI_TYPE_SINT64
            dd offset ca_epilogue       ;; FFI_TYPE_STRUCT
            dd offset ca_retint         ;; FFI_TYPE_POINTER
            dd offset ca_retint8        ;; FFI_TYPE_SMALL_STRUCT_1B
            dd offset ca_retint16       ;; FFI_TYPE_SMALL_STRUCT_2B
            dd offset ca_retint         ;; FFI_TYPE_SMALL_STRUCT_4B
    
    ca_retint8:
            ;; Load %ecx with the pointer to storage for the return value
            mov   ecx, rvalue
            mov   [ecx + 0], al
            jmp   ca_epilogue
    
    ca_retint16:
            ;; Load %ecx with the pointer to storage for the return value
            mov   ecx, rvalue
            mov   [ecx + 0], ax
            jmp   ca_epilogue
    
    ca_retint:
            ;; Load %ecx with the pointer to storage for the return value
            mov   ecx, rvalue
            mov   [ecx + 0], eax
            jmp   ca_epilogue
    
    ca_retint64:
            ;; Load %ecx with the pointer to storage for the return value
            mov   ecx, rvalue
            mov   [ecx + 0], eax
            mov   [ecx + 4], edx
            jmp   ca_epilogue
    
    ca_retfloat:
            ;; Load %ecx with the pointer to storage for the return value
            mov   ecx, rvalue
            fstp  DWORD PTR [ecx]
            jmp   ca_epilogue
    
    ca_retdouble:
            ;; Load %ecx with the pointer to storage for the return value
            mov   ecx, rvalue
            fstp  QWORD PTR [ecx]
            jmp   ca_epilogue
    
    ca_retlongdouble:
            ;; Load %ecx with the pointer to storage for the return value
            mov   ecx, rvalue
            fstp  TBYTE PTR [ecx]
            jmp   ca_epilogue
    
    ca_epilogue:
            ;; Epilogue code is autogenerated.
            ret
    ffi_call_win32 ENDP
    
    // Some more stuff
    
    #endif
    I've only shown the first function (there are a few others). As you can see, it's a strange mixture of C and x86 assembly code but the presence of #ifdef _MSC_VER near the top of the file suggests to me that it should be buildable with MSVC. However, VS2005 doesn't seem to like it very much (at least, not from within the IDE).

    What would I need to do to compile and link this module? Do I need to pre-process it somehow? Or can it only be built from a command line? Or do I need a more recent version of Visual Studio?
    "A problem well stated is a problem half solved.” - Charles F. Kettering

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

    Re: A ".S" file

    My newly found friend, the pre-build step rescued me again. All I needed to do was run this pre-build step:-

    cl /EP win32.S > win32.asm

    and then I simply compiled the resultant .asm file.
    "A problem well stated is a problem half solved.” - Charles F. Kettering

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