-4

I come here today because I am currently on a university work on introduction with assembly x86. As we did C prior this, our teacher asked us to explain this portion of code. c code associated with the problem

my basic understanding of what it does is:

  • EAX will contain the value of the memory area associated with y.
  • ECX will contain the value of the memory zone associated with EAX, ie the pointer to y.
  • imul will multiply the value of the pointer eax (i.e. the pointer to y) and the value of x.
  • We move the pointer of y in EDX, then we move the value of the multiplication to the pointer of y.

Am I right? If not, could someone give me a better explaination of the part I misunderstood?

Thank you in advance.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
  • 2
    First instruction loads the pointer to `y` into `eax`, as you say. Second loads the value of `y` into `ecx`, using the pointer. Third multiplies that value with `x`. Fourth loads the pointer to `y` again. Fifth stores the multiply result in `ecx` to `y`'s address. – 500 - Internal Server Error Sep 15 '22 at 12:54
  • thanks, I think I got it wrong with 2nd and 5th instruction. – UnusualCommonSense Sep 15 '22 at 13:11
  • 4
    [Please do not upload images of code/data/errors when asking a question.](//meta.stackoverflow.com/q/285551) – Bodo Sep 15 '22 at 13:26
  • This is inefficient compiler output; it could have kept `y` in a register across the `imul` so it could store back to the same address. The second load of `y` into EDX is redundant; it already has it in EAX. BTW, we can tell from the instruction lengths that `x` and `y` are actually aliases for something like `[ebp-4]`, local variables, not global symbols (absolute addresses). Some disassemblers like to invent names like that, like MSVC does when generating asm output in the first place. – Peter Cordes Sep 15 '22 at 17:19
  • https://godbolt.org/z/f8bGM4fdG shows GCC with optimization disabled makes asm like this even for `*y *= x`, but not clang. However, `*y = *y * x` gets clang to redundantly load `y` twice, with optimization disabled of course. With even `-O1` basic optimization enabled, compilers of course realize that they only need to load `y` once (https://godbolt.org/z/d45jYK98T - to avoid the whole function optimizing away, I had to pass the addresses of local vars to another function. I should have just used global vars, but Godbolt highlights which instructions go with which source line.) – Peter Cordes Sep 15 '22 at 17:31

2 Answers2

1

As with any assembler, you pretty much need to sit with the ISA manual at hand, because each instruction comes with a lot of flavours depending on what you pass to it.

First check out What does `dword ptr` mean? So basically this 32 bit accesses the contents at a certain address.

Since y is a pointer, the contents of y is the address where *y can be found. So first the y address will get moved into eax and then the contents of the address just uploaded into eax will be moved into ecx.

imul with two operands goes like this:

  • Two-operand form. With this form the destination operand (the first operand) is multiplied by the source operand (second operand). The destination operand is a general-purpose register and the source operand is an immediate value, a general-purpose register, or a memory location. The product is then stored in the destination operand location.

So it multiplies ecx with whatever was stored at dword ptr[x], that is the contents of x. And stores the result in ecx.

Then again the address y is uploaded to a register edx (maybe an optimization flaw, because eax already holds it). And then the result of the multiplication stored in exc is moved to that location.

Lundin
  • 195,001
  • 40
  • 254
  • 396
  • In this case, `dword ptr` is redundant and not needed since registers (eax, ecx, edx) are used. Using `dword ptr` is normally only needed for an immediate move, such as `mov dword ptr [eax],23`. Maybe this is something specific to Intel assembler. Masm would not need `dword ptr` or brackets on `x` or `y` . – rcgldr Sep 15 '22 at 19:30
  • @rcgldr I would think this code comes from disassembled C, possibly without optimizations disabled. It's always going to be more weird than hand-written assembler. – Lundin Sep 16 '22 at 06:30
0

Code with comments:

        mov     eax,dword ptr [y]         ;eax = y
        mov     ecx,dword ptr [eax]       ;ecx = *y
        imul    ecx,dword ptr [x]         ;ecx = (*y) * x
        mov     edx,dword ptr [y]         ;edx = y
        mov     dword ptr[edx], ecx       ;(*y) = (*y) * x
rcgldr
  • 27,407
  • 3
  • 36
  • 61