Social Icons

^^

segunda-feira, 15 de agosto de 2011

Delphi com assembly (Parte 5)

 -Aritmética Inteira de 128 bits (2)
==================================


No código-fonte exemplo (anexado) você encontrará a implementação de
algumas funções para operações com o tipo Hugeint que foi introduzido no
artigo passado. A proposta é exemplificar as instruções que nós vimos há
muito tempo com algumas novas:

  BT (Bit Test):

    BT dword ptr [eax], edx   --> CF = valor do EDX-ésimo bit na
                                       memória apontada por EAX

  BTS (Bit Test and Set):

    BTS dword ptr [eax], edx  --> atribui 1 para o EDX-ésimo bit na
                                  memória apontado por EAX
                                  CF = valor anterior deste bit

  BTR (Bit Test and Reset):

    BTR dword ptr [eax], edx  --> atribui 0 para o EDX-ésimo bit na
                                  memória apontado por EAX
                                  CF = valor anterior deste bit

  BTC (Bit Test and Complement):

    BTC dword ptr [eax], edx  --> inverte o valor do EDX-ésimo bit na
                                  memória apontada por EAX
                                  CF = valor anterior deste bit

Não reproduziremos as funções aqui, uma vez que você pode encontrá-los
no código-fonte anexo, mas mostraremos diferentes implementações da
função _IsNeg, simplesmente apresentando mais exemplos das instruções
que vimos tempos atrás:

  function _IsNeg(x: Hugeint): boolean;
  // Resultado := x < 0;
  // Se x < 0 retorna True (1) senão retorna False (0)
  // Parâmetros: EAX = @x
  asm
    mov eax, [eax+_3_]  // EAX := 32 bits de alta ordem de x
    shr eax, 31         // AL  := Bit de alta ordem de EAX (sign bit)
  end;

  function _IsNeg(x: Hugeint): boolean;
  asm
    cmp dword ptr [eax+_3_], 0   //   if x[3] < 0 then
    jl @@negative                //     goto @@negative
    mov al, 0                    //   Result := False;
    ret                          //   exit;
  @@negative:                    // @@negative:
    mov al, 1                    //   Result := True;
  end;

  function _IsNeg(x: Hugeint): boolean;
  asm
    // atribuir o Sign Flag e colocá-lo em AL
    mov eax, [eax+_3_]  // EAX := 32 bits de alta ordem de x
    or eax, eax         // SF := Sign bit de EAX
                        // alt.: add eax, 0
                        //   ou: sub eax, 0
                        //   ou: and eax, eax
                        //   ou: and eax, -1   // ou qq valor negativo
                        //   ou: test eax, eax
                        //   ou: test eax, -1  // ou qq valor negativo
    sets al             // AL := SF;  // Sign Flag
                        // alt.: lahf; shr ax, 31
                        //   ou: lahf; rol ax, 1; and al, $1
  end;

  function _IsNeg(x: Hugeint): boolean;
  asm
    // atribui o Carry Flag com o Sign Bit e colocá-lo em AL
    mov eax, [eax+_3_]  // EAX := 32 bits de alta ordem de x
    bt eax, 31          // CF := Sign bit de EAX
                        // alt.: shl/rol/rcl eax, 1
    setc al             // AL := CF;  // Carry Flag
                        // alt.: mov al, 0; rcl, 1
                        //   ou: mov al, 0; adc al, al
                        //   ou: lahf; mov al, ah; and al, $1
                        //   ou: lahf; ror/rcr/shr/sar ax, 1; shr al, 7
                        //   ou: lahf; ror/shr/sar ax, 8; and al, $1
                        //   ou: lahf; rol ax, 8; and al, $1
                        //   ou: lahf; rcl ax, 9; and al, $1
  end;

  function _IsNeg(x: Hugeint): boolean;
  asm
    // atribuir o Parity Flag e negá-lo em AL
    mov al, [eax+_3_+3] // EAX := 8 bits de alta ordem de x
    or al, $7F          // PF := Not Sign bit
                        // alt.: and eax, $80000000
    setnp al            // AL := Not PF;  // Not Parity Flag
                        // alt.: lahf; rol/shl ax, 6 / rcl ax, 7;
                                 xor al,-1 / not al; and al, $1;
                        //   ou: lahf; ror/shr/sar ax, 10 / rcr ax, 11;
                                 xor al,-1 / not al; and al, $1;
  end;

Na próxima parte veremos funções para adicionar, subtrair, multiplicar e
dividir inteiro HugeInt.

Nenhum comentário:

Postar um comentário

Popular Posts

 

Seguidores

Hora exata:

Total de visualizações de página