汇编程序:了解如何计算平均值

时间:2016-07-13 20:45:37

标签: assembly x86

上述守则的评论说:从记忆地址A中计算N个数字。该守则仅用于教育目的......

我试图理解平均值的计算如何在汇编程序中起作用。代码评论由我撰写。如果我理解错误请将其添加到您的答案中。我不理解的部分尤为ADD EBX,4

本规范的目的是获取内存地址A中所有数字的平均值。请仔细阅读评论。

MOV ECX, [N]      ;Loading count of numbers in ECX
JZ done           ; If the count of numbers is 0 go to done
MOV EBX, [A]      ; Load all the numbers which are in memory space [A] in EBX
MOV EAX,0         ; EAX will be the result
Loop: ADD EAX, [EBX] ;Add first number of EBX to EAX?
ADD EBX, 4           ;What is this doing and how does it work, why would you add the number 4?
DEC ECX              ;Numbers to add - 1
JNZ Loop             ;Jump if not zero, and repeat the loop
DIV [N]              ;Divide the result of the calculation
Done: ;value of average in EAX

问题在代码评论中。 向我提供[A][N]是什么以及它们如何运作的信息,特别是ADD EBX,4正在做什么?谢谢。

2 个答案:

答案 0 :(得分:2)

让我们从变量“N”和“A”的定义开始,它们看起来像这样:

if gender == true {
   self.genderSelection.selectedSegmentIndex = 0
} else if gender == false {
   self.genderSelection.selectedSegmentIndex = 1
}

我们现在“N”是“dd”类型,因为在你的代码中“N”被分配给注册“ECX”,其大小为32位:

.data
  N     dd 5
  ARRAY dd 1,2,3,4,5
  A     dd ?

“A”是指向数组数组的指针(如@MichaelPetch指出的那样),因为寄存器“EBX”设置为“[A]”并且其值在每个循环中被添加到EAX:

MOV ECX, [N]      ;Loading count of numbers in ECX

顺便说一下,标签“Loop:”可能是个问题,因为这是一个指令的名称,让我们用“Loopy:”改变名称:

mov [A], offset ARRAY      ;A IS THE ADDRES OF THE ARRAY OF NUMBERS.
MOV EBX, [A]               ;IN IDEAL MODE VARIABLES VALUE IS ACCESSED WITH BRACKETS.
...
Loop: ADD EAX, [EBX] ;Add first number of EBX to EAX?

注册“EBX”用作指向数组“ARRAY”的指针:

Loopy: ADD EAX, [EBX] ;Add first number of EBX to EAX?
...
JNZ Loopy             ;Jump if not zero, and repeat the loop

这个指针必须向前移动,第一次指向“1”(数组中的第一个数字“ARRAY”指向“A”),使其指向其余数字,我们必须添加每个循环上都有“4”,因为数组“ARRAY”(由“A”指向)是“dd”类型,这意味着每个元素的大小为4个字节:

mov [A], offset ARRAY  ;A IS THE ADDRES OF THE ARRAY OF NUMBERS.
MOV EBX, [A]           ; Load all the numbers which are in memory space [A] in EBX

最后,除以“[N]”:

ADD EBX, 4           ;What is this doing and how does it work, why would you add the number 4?

“DIV”指令,当值为“dd”时也使用“EDX”寄存器,因此清除“EDX”以避免错误结果是一个很好的理想选择:

DIV [N]              ;Divide the result of the calculation

现在“EDX”为0,除法将仅划分“EAX”,并获得平均值。

答案 1 :(得分:2)

MOV ECX, [N]      ;Loading count of numbers in ECX
JZ done           ; If the count of numbers is 0 go to done

第二条评论错了。 mov不会改变ZF,因此条件跳转将发生在来自调用者的ZF值上。

要让代码按照注释建议运行,您必须像这样测试获取的值:

MOV ECX, [N]      ;Loading count of numbers in ECX
TEST ecx,ecx      ; do virtual "AND ecx,ecx" and set only flags
JZ done           ; If the count of numbers is 0 go to done

CMP ecx,0JZ可由JECXZ替换而无需设置ZF。 (或者可能有数百万种其他神秘的方式,当ecx为零时如何设置一些标志,而不更改内容......有人提到OR ecx,ecx ......)