所以我试图在给定数字n的情况下求和1 + 11 + 111,这决定了我加在一起的系列的值。即n = 2,我将添加1 + 11,或n = 3,我将添加1 + 11 + 111.我已经在C中编写了该函数,但我试图将其转换为x86汇编并且我遇到了问题。 这是C函数:
int summation(int n)
{
int sum = 0, j = 1;
for (int i = 1; i <= n; i++)
{
sum = sum + j;
// Appending a 1 at the end
j = (j * 10) + 1;
}
return sum;
这是我的x86汇编代码:
unsigned int seriesSum(int n)
{
unsigned int sum=0;
__asm
{
mov ebx, n //input n
mov eax, 1
mov ecx, 10
mov edx, 0
Begin:
cmp ebx, 0 // determines end of loop or not
je EndOfWhile
add edx, edx
add edx, eax
mul ecx
add eax, eax
inc eax
dec ebx
jmp Begin //Loop back
EndOfWhile:
mov sum, edx
}
return sum;
我以为我已经正确翻译但我似乎得到0作为我的总和。
答案 0 :(得分:2)
您正在使用edx
来保存您的金额,但mul ecx
指令会将结果的高位字放入edx
中。
答案 1 :(得分:1)
使用imul eax, ecx
只执行eax *= ecx
而不将高半部分存储在任何位置。 (单操作数imul
是一个完全乘法,用于将结果存储在edx:eax
中。)
或者甚至更好,x86中的eax = eax*10 +1
最好使用add eax,eax
/ lea eax, [eax+eax*4 + 1]
,而不是mul
或imul
。实际上,优化延迟而不是代码大小,你需要avoid the 3-component LEA将其拆分为
lea eax, [eax + eax*4] ; eax *= 5
lea eax, [1 + eax*2] ; NOT [ 1 + eax + eax ], which is shorter but slower
; eax = orig_eax*5*2 + 1
NASM和YASM将代码大小优化为[ 1 + eax + eax*1 ]
(因此可以使用base + scaled-index + disp8
代替disp32 + scaled-index
)。我不知道如何覆盖寻址模式; [dword 1 + eax*2]
使用了disp32,但仍将eax*2
拆分为eax + eax*1
,而strict eax*2
未汇编。希望How to force NASM to encode [1 + rax*2] as disp32 + index*2 instead of disp8 + base + index?
显然,MASM会有所不同,但我没有MASM。