Assembly Line Programming

1
2
3
4
5
6
7
8
9
//x at %ebp+8, y at %ebp+12, z at %ebp+16

      movl      12(%ebp), %edx
      subl      16(%ebp), %edx
      movl      %edx, %eax
      sall      $31, %eax
      sarl      $31, %eax
      imull     8(%ebp), %edx
      xorl      %edx, %eax


Need someone to verify this is the correct representation of the above assembly code to C:

1
2
3
4
5
6
7
8
9
int decode1(int x, int y, int z) {
   y - z;
   int *yp = y;
   *yp << 31;
   *yp >>a 31;
   y * x;
   *yp ^ y;
   return y;
}


Your help is much appreciated!
Last edited on
New discovery I have made so far from reading:

This is a link to a figure in my textbook with more on understanding Assembly code to C:
http://bayimg.com/HanfFAaEp
C and assembly code for exchange routine body. The stack set-up and completion portions have been omitted.

What I take from it is that variable representations are stated by default - for this example - in Assembly (I don't understand how), movl represents starting a new line (like how ; represents end of a line in C), and variables default values have to be assigned an address in assembly(i.e. every stated variable in assembly must be in the format %e[insert char here]x).

Does this mean in assembly you are only limited to having %eax - %ezx for storing variables? Making a max of 26 variables in use at once without reassigning them? Is this stuff I'm saying sound right so far?
Last edited on
*bump*
It might help to rethink of the parameters as special constant values to help you keep track of them, as the registers are the only "real" variables you actually have access to with most operations.

From your crossed out posts it seems you don't understand exactly how that works, so here's a small explanation that I hope helps: When dealing with assembly like this, you have "registers" (eax and such) that store the values used in calculations. These are basically your variables. Passed values are, in this case, stored on the stack. ebp indicates where the stack is, so you offset it (like indexing into an array) to get the parameters values.

1
2
3
4
5
6
7
8
9
10
11
const int x; // passed value of x (ebp_8, if you will)
const int y; // passed value of y
const int z; // passed value of z
// now for the assembly
edx = y;
edx -= z;
eax = edx;
eax <<= 31;
eax >>= 31;
edx *= x;
eax ^= edx;


From here is (to me, at least) simpler to convert to C by sort of hand-optimizing out the register "variables" I pretended existed and replacing them with the actual variables x, y, z where appropriate.

Also something important that you should note is that arithmetic operations in assembly here store their result in the destination (second) operand. So the imul instruction doesn't just multiply two numbers and do nothing with the result, as you wrote in your C code (what would be the point of such an instruction?), but is actually equivalent to the *= operator.
1
2
3
4
5
6
7
edx = y;
edx -= z;
eax = edx;
eax <<= 31;
eax >>= 31;
edx *= x;
eax ^= edx;

I wrote the same psuedocode out on paper before typing it up in VS, except without the (=) signs. Very helpful you mentioned that, as this work with assembly line code is really frustrating reading it from the textbook. The only question I have is concerning register %eax. Wouldn't it be representative of a pointer since its assigned the value of y from the register %edx?
The register as implemented in hardware is actually a storage location. So when you mov data into it, you can consider yourself actually writing to a block of memory labelled "eax" or whatever the case is. I don't think it would be correct to think of eax and such as a pointers in this case because when you mov the contents at memory location ebp+8 into eax, changing what is at ebp+8 or eax does not affect the other.

Just as you say, eax is being populated with the value of y, which is located at the address ebp+12. This understanding is your clue you are seeing the register being used to store data and not addresses.

However, this doesn't prevent you from using those registers as such! You can load memory addresses into them and dereference them like pointers should you choose to do so. In this case, though, they are being used like "standard" variables.

Note, as an example, that ebp is a register that holds a memory address; the base of the stack. In case your book hasn't noted this, the "bp" stands for "base pointer".
Much appreciation for the help!
Happy to be of help.
Topic archived. No new replies allowed.