在x86汇编中求和1 + 11 + 111 ... n项

时间:2018-02-17 21:04:01

标签: x86 inline-assembly

所以我试图在给定数字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作为我的总和。

2 个答案:

答案 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],而不是mulimul。实际上,优化延迟而不是代码大小,你需要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。