Вычислить -2xy - 3z с помощью встроенной сборки MSVC

Ребята, вы можете сказать мне, где я ошибаюсь?

Мне нужно вычислить это в inline-сборке -2xy - 3z.

int solution(int x, int y, int z)
{ 
    x=4;
    y=5;
    z=2;
    int result;
    __asm
    {   
       mov eax, -2 
       imul [x]
       imul [y]
       mov ebx, eax 
       mov eax, -3
       imul [z]
       sub eax, ebx 


        mov [result], eax       ; 
    }
       assert(result == -2*x*y – 3*z);
       printf("solution_for_grade_6(%d, %d,**strong text** %d) = %d\n", x, y, z, result);
 return result;

1 ответ

Это мое пятое решение (вернуть 32-битное значение; я удалил четвертое и третье ошибочные / неоптимизированные решения); он использует только один IMUL; обратите внимание, что оба abs(X) и& abs(Y) не могут быть> (1<< 14) -1, abs(Z) должно быть <(1 << 29):

__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
}

Это мое второе решение (верните 64-битное значение); он использует только один IMUL; сейчас оптимизирован. Обратите внимание, что оба abs(X) и& abs(Y) не могут быть> (1<<30)-1. Я предположил, что в данном случае RESULT представляет собой 64-битное целое число:

__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
}

Но помните, что каждый из двух продуктов имеет результат более 64 бит; в сборке (вернуть значение 96 бит):

 ; -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)
Другие вопросы по тегам