2

私はアセンブリとメモリ関連のものの初心者です。reg 内に int64 値がある場合、mov 演算子はそれをどのように変更しますか? つまり、文字列ではなく整数です。多分それは私のばかげているかもしれませんが、私は理解していません! たとえば、このコードは何をしますか? 「esp」に int64 値があるとします。

 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 には 8 バイトありますが、esp+$10 に対応しています !!!

4

1 に答える 1

5

_llmulこれは、質問で見た非常に役立つ情報のためのコードです。関係なく、_llmul32 ビット マシンで 64 ビットの整数乗算を実行するヘルパー関数です。

関数のソース コードは次のようになります。

// 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;

PUSHこれにより、2 つの演算の後、オペランドが と にあることが明らかに[ESP+16]:[ESP+12]なり[ESP+4]:[ESP]ます。

[ESP+8]関数の戻りアドレスが表示されます。

MUL関数の設計全体は、32 ビットのオペランドを操作する場合、演算が 64 ビットの結果を返すという事実に依存していますEDX:EAXしたがって、この関数は基本的に、2 つの 32 ビット数字として扱われるオペランドに対して長い乗算を実行します。

オペランドをH1:L1H2:L2H表し、 は上位 32 ビットをL表し、 は下位 32 ビットを表します。次に、最初の 2 つの乗算はH1*L2H2*L1です。結果の上位部分 inEDXは、64 ビットの結果に収まらないため無視されます。最後の掛け算はL1*L2、最初の 2 つの掛け算の低い部分と組み合わせた高い部分です。明らかに適合しないため、H1*H2試みさえされていません。この関数はオーバーフローを無視します。

于 2013-08-05T16:10:44.633 に答える