Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any larger significance to this piece of translated assembly code?

For a short homework assignment in CS Architecture, we were made to translate the following IA-32 assembly into C. I've translated it properly (as far as I know) but the code doesn't appear to do anything particularly useful. My professor typically gives us problems like this which end up doing something: our last assignment like this was a bit pop_count. Looking at the C code below, does this function do anything useful? Some algorithm maybe?

The code appears below (I've added comments to each ASM line).

// The following variables x, y, z are located at (%ebp) +8, +12, +16 respectively
// x, y, and z, are scanned from the terminal and passed into the function

   movl 12(%ebp), %edx                  // moves long y to register %edx
   subl 16(%ebp), %edx                  // subtracts longs: y = y - z
   movl %edx, %eax                      // moves long y to register %eax
   sall $31, %eax                       // left shift all bits in long y by 31 places 
   sarl $31, %eax                       // arithmetic right shift long y by 31 places
   imull 8(%ebp), %edx                  // multiply longs: unshifted y = y * x
   xorl %edx, %eax                      // XOR operation: shifted y = shifted y ^ unshifted y

// The returned value is stored in register %eax

The effective takeaway is we subtract z from y, then populate every bit with the least significant bit to form either zero or MAX_UINT. This is XOR'd with the product of (y - z) * x and returned.

My translation into C:

return (((y - z) << 31) >> 31) ^ ((y - z) * x);

// In more words:
    int f;
    y -= z;
    f = y << 31;                        // These two lines populate all bits with the lsb
    f = f >> 31;                        // Effectively, if y-z is odd: f is ~0; else f is 0
    y *= x;
    return y ^ f;

// Or, using people logic:
    y -= z;
    if (y % 2 == 0) return y * x;
    return -(y * x) - 1;

// If the y-z is odd, the result will be:    -1 * ((y - z) * x) - 1
// If the y-z is even, the result will be:              (y - z) * x

For clarification, this is not part of the HW assignment; I've completed the assignment by translating the code, but I'm interested in knowing why he gave us this code to begin with.

like image 286
SeniorShizzle Avatar asked Mar 27 '15 19:03

SeniorShizzle


People also ask

What is the significance of the assembly language?

An assembly language is a programming language that communicates with the hardware of a computer directly. An assembly language allows a software developer to code using words and expressions that can be easier to understand and interpret than the binary or hexadecimal data the computer stores and reads.

Does assembly code need to be translated?

Assemblers. In order to convert assembly language into machine code it needs to be translated using an assembler . This converts each statement into the specific machine code needed for the hardware on which it is being run.

What is the main purpose of assembly language what are the advantages of assembly language over machine language?

Assembly language makes it faster to run complex code. It is incredibly difficult to write code in assembly language compared to high-level languages. Simpler for humans to understand than machine-level language. The syntax is hard to learn and can be difficult to remember or use quickly.

Why is assembly language so powerful?

Assembly language has a very strong correspondence with the architecture's machine code instruction and is specific only to that machine. Therefore, different machines have different assembly languages. This type of language makes use of symbols to represent an operation or instruction.


1 Answers

My guess is that your professor was trying to illustrate how you can use bit-shifting/masking operations to avoid branches. If you were to naively translate

y -= z;
if (y % 2 == 0) return y * x;
return -(y * x) - 1;

into machine code, you would use a branch instruction for the conditional. Branches can dramatically slow down your code, especially if they're inside a tight loop*. The assembly code and your preceding C code have the effect of using a conditional on whether or not y - z is even, but only using arithmetic instructions.

*If you're not already familiar with this fact, this SO answer has one of my favorite illustrations of it.

like image 78
Daniel Shapero Avatar answered Oct 04 '22 00:10

Daniel Shapero