Thread: ASM to C language

  1. #1
    Registered User
    Join Date
    Jun 2009
    Posts
    93

    ASM to C language

    I am hoping someone could shed some light on a possible ASM to C language translation of some ASM code.
    OK, first off let me say that I know basically nothing about C language programming, or any language programming for that matter.
    This little chunk of ASM code has been bothering me in regard to a C language translation.

    mov eax, [eax - 33] ; mov data from somewhere to eax
    cdq ; convert double to quad
    shl edx, 8 ; shift left edx c << 8;
    sbb eax, edx ; subtract with borrow
    sar eax 8 ; shift right eax c >> 8;

    I know the translation between ASM and C isn't nessarily easy, but it seems a lot of the ASM instructions can be generalized in some type of C expression I guess. What confuses me about the ASM code I posted is the cdq, sbb instructions, and in this case the use of cdq when it's not followed by idiv.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    x86 instruction listings - Wikipedia, the free encyclopedia
    Sign-extends EAX into EDX, forming the quad-word EDX:EAX. Since (I)DIV uses EDX:EAX as its input, CDQ must be called after setting EAX if EDX is not manually initialized (as in 64/32 division) before (I)DIV.
    Basically, EDX becomes 0x00000000 or 0xFFFFFFFF depending on the sign of EAX
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Basically, in a compiler that supports 64-bit operations, this should do it:
    Code:
    int x = somewhere;
    int64 y = x << 8;
    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  4. #4
    Registered User
    Join Date
    Jun 2009
    Posts
    93
    I know that the code I posted is 32-bit (Watcom 9.01d), so I'd assume 64-bit operations are out of the question since this version of Watcom doesn't support "long long". I keep reading about "sign-extends" in regard to a cdq ASM operation, but for some reason I just can't grasp the concept......In the case of modulus "%" I understand, but not when there's cdq NOT followed by idiv. So, how would one sign-extends eax into edx when no division is to take place in 32-bit mode in C language?

  5. #5
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Sign extension has nothing whatsoever to do with division? Sign extension just says "I need more bits: if the number is positive, make them 0; if the number is negative, make them 1." (The point being, doing it that way keeps the value of the number the same, even with the extra bits, assuming general 2's complement notation.)

  6. #6
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    So, you want to do the same thing in a different compiler, or are you using Watcom 9.x? If you use a modern compiler, it should work to just use a 64-bit int. it gets rather complicated to do this with only 32-bit C code.

    Sign extension is when you take a small integer - to make it simple, short converted to int:
    16 bits of signed data (short) need to be made into 32-bits of signed form. That means that anything from 0x0000 to 0x7FFF becomes 0x00000000 to 0x00007FFFF, and 0x8000 to 0xFFFF becomes 0xFFFF8000 to 0xFFFFFFFFF. The principle being that the SIGN bit (15th bit in a 16-bit number) is filled into the rest of the number. Same obviously applies for 32-bit to 64-bit or 64-bit to 128-bit signed numbers [and 8-bit to 16-/32-bit integers, e.g. a signed form of char to short or integer].

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  7. #7
    Registered User
    Join Date
    Jun 2009
    Posts
    93
    I'm actually using the same compiler Watcom 9.01d. So, lets say the integer is 8074 (int a = 8074). Since the compiler only supports up to 32-bit operations should I assume "int a;" is a short?

    mov eax, [eax - 33] ; mov 8074 (hex 0x00001F8A) into eax

    now what happens???

  8. #8
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Why do you need to:
    1. Use Watcom compiler - there are several other compilers that are a few years less than 14 years old - old age is NOT an advantage in compilers?
    2. Translate this FROM assembler?

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  9. #9
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by tabstop View Post
    Sign extension has nothing whatsoever to do with division? Sign extension just says "I need more bits: if the number is positive, make them 0; if the number is negative, make them 1." (The point being, doing it that way keeps the value of the number the same, even with the extra bits, assuming general 2's complement notation.)
    Yes, but the most common reason this is done is in preparation for a 32-bit division operation. On x86, you can divide a 64-bit quantity by a 32-bit quantity, or a 32-bit quantity by a 16-bit quantity. But in C, you commonly divide two 32-bit quantities, so the numerator first has to been sign-extended in order to allow the division by a 32-bit denominator
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  10. #10
    Registered User
    Join Date
    Jun 2009
    Posts
    93
    OK, short version of a long story:
    I recently fired up an old computer (Windows 95 updated to Window 98 first edition) and while browsing through some of my old files I came across this stuff I must have been working on at one time. So, some 11 years later this "unfinished" stuff has recaptured my attention for no other reason than to solve the this puzzle. The reason why I'm using Watcom 9.01d is because that's what's on the old computer.

  11. #11
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    So, that explains why you are using an ancient computer. Not why you need to translate this to C!

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  12. #12
    Registered User
    Join Date
    Jun 2009
    Posts
    93
    Yes, but the most common reason this is done is in preparation for a 32-bit division operation. On x86, you can divide a 64-bit quantity by a 32-bit quantity, or a 32-bit quantity by a 16-bit quantity. But in C, you commonly divide two 32-bit quantities, so the numerator first has to been sign-extended in order to allow the division by a 32-bit denominator
    This is one reason why I'm confused with the cdq operation in the ASM code I posted since there is 32-bit division following the cdq......Rather, you find a shift left instead.

  13. #13
    Registered User
    Join Date
    Dec 2008
    Location
    Black River
    Posts
    128
    Doesn't Watcom C support __int64? If not, then see if it has stdint.h and look for int64_t

  14. #14
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    But cdq is not DIRECTLY related to divide instructions - it's simply OFTEN used together with divide instructions, because to get a 32-bit result in divide, you need a 64-bit input [that's just the way the processor is designed].

    And by the way, I'm not sure I'm right on the analysis of what the code does. I think it's actually a divide by 256 and modulo 256 "in one".

    So resembling the normal divide instruciton, but using much faster shift instructions instead.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  15. #15
    Registered User
    Join Date
    Jun 2009
    Posts
    93
    So, that explains why you are using an ancient computer. Not why you need to translate this to C!
    The ASM code was from a program written in C language......I retrieved the ASM code via SoftIce when I was messing around with trying to write an ADS application for a program. The retrieved ASM code was to be the outline for what I was going write in the application. Anyhow, in the notes I left there was this confusion surrounding three of the lines of ASM code which I posted initially.

    cdq
    shl edx, 8
    sbb eax, edx

    I went on to write (in my notes) that the ASM code basically did nothing and was not needed in the application I was writting. Now, some 11 years later it still nags me that I couldn't translate these three operations to C language.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Language of choice after C++
    By gandalf_bar in forum A Brief History of Cprogramming.com
    Replies: 47
    Last Post: 06-15-2004, 01:20 AM
  2. How to use asm code in c language
    By phijo in forum C Programming
    Replies: 5
    Last Post: 05-08-2004, 02:58 AM
  3. True ASM vs. Fake ASM ????
    By DavidP in forum A Brief History of Cprogramming.com
    Replies: 7
    Last Post: 04-02-2003, 04:28 AM
  4. Understanding ASM
    By kuphryn in forum A Brief History of Cprogramming.com
    Replies: 26
    Last Post: 07-12-2002, 07:39 PM
  5. My graphics library
    By stupid_mutt in forum C Programming
    Replies: 3
    Last Post: 11-26-2001, 06:05 PM