上述守则的评论说:从记忆地址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
正在做什么?谢谢。
答案 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,0
或JZ
可由JECXZ
替换而无需设置ZF。 (或者可能有数百万种其他神秘的方式,当ecx为零时如何设置一些标志,而不更改内容......有人提到OR ecx,ecx
......)