需要循环帮助以迭代地添加到汇编中的总和变量

Posted

技术标签:

【中文标题】需要循环帮助以迭代地添加到汇编中的总和变量【英文标题】:Need assistance with loop to iteratively add to sum variable in Assembly 【发布时间】:2020-05-20 00:03:57 【问题描述】:

我正在尝试将以下 C++ 代码转换为程序集(MASM,Irvine32):

const int SIZE = 10;

int numbers[SIZE] = 10,60,20,33,72,89,45,65,72,18;
int limit = 50;
int index = 0;
int sum = 0;

while( index < SIZE )

    if( numbers[index] <= limit )
    
        sum = sum + numbers[index];         // sum += array[index];
    
    index++;

如果有人能弄清楚我哪里出错了——我在 L1 上遇到了错误:它只是在喷出“+10”。我相信这是因为我无法将 sum=sum+numbers[index] 翻译成汇编。如果有人可以帮助我做到这一点,那就太好了。我试图翻译它(从“total: mov esi, offset numbers”到“inc index”的行)显然是不正确的。

.data
SYZ = 10
numbers DWORD 10, 60, 20, 33, 72, 89, 45, 65, 72, 18
limit DWORD 50
index DWORD 0
sum DWORD 0

.code
main PROC
mov eax, index
mov ebx, SYZ
top: cmp eax, ebx
jae next
jb total

total: mov esi, OFFSET numbers
mov ecx, limit

cmp [esi], ecx

jbe L1

L1: add eax, ebx

inc index

jmp top

next: mov edx, sum

call WriteInt



exit
main ENDP
END main

【问题讨论】:

有点与实际问题无关,但我认为“jb total”指令是不必要的,如果“jae next”没有跳转,它将落入下一条指令(其中有标签总数)无论如何,这意味着它是一个多余的检查。 谢谢你的检查,你觉得这是多余的 【参考方案1】:

您实现if 的条件分支是错误的。它应该看起来像:

top:
...
    cmp [esi], ecx
    ja L1               ; conditional jump *over* an ADD instruction
    add eax, [esi]      ; [esi] is array[index] if you increment ESI properly...
L1: inc index
    jmp top

在您的 C++ 中,您可以看到如果 numbers[index] &lt;= limit 则您想要更新总和,否则只需增加索引并返回“顶部”;也就是重新检查停止条件。

您的原始 asm 代码正在执行条件检查,然后不管结果如何都继续。

    cmp [esi], ecx
    jbe L1               ; jump or fall-through to L1, condition irrelevant
L1: add eax, ebx

原始 asm 的 C++ 等效项是:

if( numbers[index] <= limit )



    sum += ebx;
    index++;

我不确定这是否能解决您的所有问题,但肯定会解决其中一个问题。

【讨论】:

除了cmp之外,您提议的新循环片段仍然没有向循环添加另一个内存访问,因此它没有访问numbers[index]。从我从 OP 循环中的混乱中可以看出,它每次迭代都在访问numbers[0]。您已经正确识别了问题,即条件分支需要跳转 over 某些东西,而不仅仅是跳转到下一条指令,无论它是通过还是被采用,但 add eax, ebx 肯定没有实现sum += numbers[index]; 因为没有将数组值放入 EBX。 另外它不是否则增加索引。无论分支条件如何,您总是 递增索引(add esi, 4 移动指针)。也许您的意思是“否则只是增加索引(不做任何其他事情)”。 哦,我错过了你回答的最后一行,你说这可能不是一个完整的解决方案。抱歉,直到投票后才注意到这一点。说“试试这个”通常是开始回答的不好方式,尤其是当它实际上并不能解决所有问题时,所以在我到达你最终解释原因的部分之前,这给了我这个答案的坏印象。 我进行了编辑以使您的答案更具可读性,IMO(因此我可以删除我匆忙投下的反对票)。无论如何,是的,这只是问题中代码中的多个显示问题之一;我在您的第一个代码块的编辑中添加了另一个提示。【参考方案2】:
.data
SYZ = 10
numbers DWORD 10, 60, 20, 33, 72, 89, 45, 65, 72, 18
limit DWORD 50
index DWORD 0
sum DWORD 0

.code
main PROC
mov eax, index
mov ebx, SYZ
mov esi, OFFSET numbers
mov ecx, limit
mov edx, 0

top: cmp eax, ebx
jae next
cmp [esi], ecx
ja L1
add edx, [esi]
L1: inc index
mov eax, index
add esi, 4
jmp top

next: mov sum, edx
      mov eax, sum
      call WriteInt

【讨论】:

以上是关于需要循环帮助以迭代地添加到汇编中的总和变量的主要内容,如果未能解决你的问题,请参考以下文章

我想在 for 循环中串联运行多个变量,我想取 x 和 y 的每次迭代的总和

比较两个数组中的项目以查看它们的总和是不是为 10

有没有办法在汇编中的一行上显示一个循环?

Go语言:利用 TDD 测试驱动开发帮助理解数组与动态数组(切片)的区别

编辑数字直到达到总和值

将订单集合中的订单总和添加到猫鼬中的用户集合