V¡®u§ 849 Posted January 7, 2012 -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. Share this post Link to post Share on other sites