使用MSVC内嵌程序集计算-2xy - 3z
你们能告诉我我在哪里弄错了吗?使用MSVC内嵌程序集计算-2xy - 3z
我需要在inline-assembly -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;
这是我的第五溶液(返回一个32位的值;我已删除第四和第三错误/ UN优化的解决方案);它只使用一个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。我推测,因此,在这种情况下,是一个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)
但是,如果您在独立功能中使用它,则必须在此代码之前/之后保存/恢复EBX,ESI,EDI和EBP寄存器... –
不要使用push/pop来保存/恢复inline-asm语句。让编译器为你做,如果需要的话。 (它可能不会在内联到一个已经保存/恢复这些regs的函数之后,但是当这段代码运行时它们没有任何有价值的东西)。 –
'add edi,edi'比'shl edi,1'更有效率,并将CF设置完全相同。 –
什么处理器你写的asm? 另外,运行代码时会得到什么样的错误? 更多信息可帮助他人更快地获得答案。 –
它用于IA-32。我没有得到一个错误,它运行但没有发生在窗口上。 – konstantin97
我看到的唯一错误是'sub eax,ebx'应该是'add eax,ebx',因为你乘以-3,并且已经做了否定。你可以用'3'而不是'-3'来倍数,并保持'sub eax,ebx'的原样。 –