Pregunta

I'm beginner in assembly and memory related stuffs. When we have int64 value inside a reg, the mov operator how changes that? I mean it is not a string but integer. Maybe it is silly of me but I do not understand ! for example what this code does? assume that we have a int64 value at "esp".

 push       edx
 push       eax
 mov        eax,dword ptr [esp+$10]
 mul        eax,dword ptr [esp]
 mov        ecx,eax
 mov        eax,dword ptr [esp+$04]
 mul        eax,dword ptr [esp+$0C]
 add        ecx,eax
 mov        eax,dword ptr [esp]
 mul        eax,dword ptr [esp+$0C]
 add        edx,ecx
 pop        ecx
 pop        ecx
 ret        8

int64 has 8 bytes but it addresses esp+$10 !!!

¿Fue útil?

Solución

This is the code for _llmul, information that would have been quite useful to have seen in the question. No matter, _llmul is a helper function that performs 64 bit integer multiplication on a 32 bit machine.

The source code for the function looks like this:

// 64 bit integer helper routines
//
// These functions always return the 64-bit result in EAX:EDX

// ------------------------------------------------------------------------------
//  64-bit signed multiply
// ------------------------------------------------------------------------------
//
//  Param 1(EAX:EDX), Param 2([ESP+8]:[ESP+4])  ; before reg pushing
//

procedure __llmul;
asm
        push  edx
        push  eax

  // Param2 : [ESP+16]:[ESP+12]  (hi:lo)
  // Param1 : [ESP+4]:[ESP]      (hi:lo)

        mov   eax, [esp+16]
        mul   dword ptr [esp]
        mov   ecx, eax

        mov   eax, [esp+4]
        mul   dword ptr [esp+12]
        add   ecx, eax

        mov   eax, [esp]
        mul   dword ptr [esp+12]
        add   edx, ecx

        pop   ecx
        pop   ecx

        ret     8
end;

This makes it clear that, after the two PUSH operations, the operands are to found in [ESP+16]:[ESP+12] and [ESP+4]:[ESP].

At [ESP+8] you will find the function's return address.

The entire design of the function, relies on the fact that the MUL operation, when operating on 32 bit operands, returns a 64 bit result in EDX:EAX. So the function is essentially performing long multiplication on operands that are being treated as two 32 bit digits.

Let's denote the operands by H1:L1 and H2:L2 where H denotes the high 32 bits, and L denotes the low 32 bits. Then the first two multiplications are H1*L2 and H2*L1. The high part of the result, in EDX is ignored since it won't fit in a 64 bit result. The final multiplication is L1*L2 with the high part of that being combined with the low parts of the first two multiplications. And H1*H2 is not even attempted since clearly it won't fit. This function ignores overflow.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top