Ceci est ma cinquième solution (renvoie une valeur de 32 bits, j'ai supprimé les quatrième et troisième solutions erronées/UN-optimisées); il utilise seulement un IMUL; noter qu'ils ne pouvaient pas être> (1 < < 14) -1, abs (Z) doit être < (1 < < 29), les deux abs (X) & & abs (Y):
__asm
{
/* INPUT: EAX= X */
/* EDX= Y */
/* EBX= Z */
/* TEMP: EDX */
/* OUTPUT: EAX= -2*xy-3*z) */
NEG EAX
IMUL EDX /* EDX:EAX=-x*y */
ADD EAX,EAX /* EAX=-2*x*y */
LEA EDX,[EBX+EBX]
ADD EDX,EBX
SUB EAX,EDX /* EAX=-2*x*y-z*3 */
MOV [RESULT],EAX
}
Cette est ma deuxième solution (renvoie une valeur de 64 bits); il utilise seulement un IMUL; maintenant est optimisé. Notez que les deux abs (X) & & abs (Y) ils ne pouvaient pas être> (1 < < 30) -1. Je suis supposé ce résultat, dans ce cas, est un entier de 64 bits:
__asm
{
/* INPUT: EAX= X */
/* EDX= Y */
/* EBX= Z */
/* TEMP: ESI, EDI */
/* OUTPUT: EDX:EAX= -(2*xy+3*z) */
IMUL EDX
ADD EAX,EAX
ADC EDX,EDX /* EDX:EAX=2*xy */
MOV ESI,EBX
ADD ESI,ESI
SBB EDI,EDI /* EDI:ESI=2*z */
ADD ESI,EBX
ADC EDI,EDI /* EDI:ESI=3*z */
ADD EAX,ESI
ADC EDX,EDI /* EDX:EAX=2*xy+z*3 */
NOT EAX
NOT EDX
ADD EAX,1
ADC EDX,0 /* EDX:EAX=-(2*xy+z*3) */
LEA ESI,[RESULT]
MOV [ESI],EAX
MOV [ESI+4],EDX
}
Mais rappelez-vous que chacun des deux produits a un résultat de plus de 64 bits; dans l'assemblage (retourne une valeur de 96 bits):
; -2xy-3z=-(2*xy+3*z)
; INPUT: EAX= X
; EDX= Y
; ECX= Z
; TEMP: EDI, ESI, EBP
; OUTPUT: EBX:EDX:EAX= -(2*xy+3*z)
IMUL EDX
ADD EAX,EAX
RCL EDX,1
SBB EBX,EBX ;EBX:EDX:EAX=2*xy
MOV ESI,ECX
ADD ESI,ESI
SBB EDI,EDI
MOV EBP,EDI ;EBP:EDI:ESI=z*2
ADD ESI,ECX
ADC EDI,EDI
ADC EBP,EBP ;EBP:EDI:ESI=z*3
ADD EAX,ESI
ADC EDX,EDI
ADC EBX,EBP ;EBX:EDX:EAX=2*xy+z*3
NOT EAX
NOT EDX
NOT EBX
ADD EAX,1
ADC EDX,0
ADC EBX,0 ;EBX:EDX:EAX=-(2*xy+z*3)
Pour quel processeur rédigez-vous l'ASM? En outre, quel type d'erreur obtenez-vous lorsque vous exécutez le code? D'autres informations aideront les autres à trouver la réponse plus rapidement. –
Son pour IA-32. Je n'ai pas d'erreur, ça marche mais rien ne se passe sur la fenêtre. – konstantin97
La seule erreur que je vois est que 'sub eax, ebx' devrait être' ajouter eax, ebx' puisque vous avez multiplié par '-3' et avez déjà fait la négation. Vous pouvez multiplier par '3' au lieu de' -3' et garder le 'sous eax, ebx' tel quel. –