[英]Assembler: Understanding how to calculate an average
上面代码的注释说:从内存地址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
在做什么? 谢谢。
让我们从变量“ N”和“ A”的定义开始,它们看起来像这样:
.data
N dd 5
ARRAY dd 1,2,3,4,5
A dd ?
现在,我们“ N”的类型为“ dd”,因为在您的代码“ N”中分配了大小为32位的寄存器“ ECX”:
MOV ECX, [N] ;Loading count of numbers in ECX
“ A”是指向数字数组的指针(如@MichaelPetch所指出的),因为寄存器“ EBX”设置为“ [A]”,并且其值在每个循环中都添加到EAX:
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?
顺便说一句,标签“ Loop:”可能是一个问题,因为那是一条指令的名称,让我们通过“ Loopy:”来更改名称:
Loopy: ADD EAX, [EBX] ;Add first number of EBX to EAX?
...
JNZ Loopy ;Jump if not zero, and repeat the loop
寄存器“ EBX”用作指向数字数组“ ARRAY”的指针:
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
该指针必须向前移动,第一次指向“ 1”(数组“ ARRAY”中的第一个数字由“ A”指向),要使其指向其余数字,我们必须添加“ 4”在每个循环中,由于数组“ ARRAY”(由“ A”指向)的类型为“ dd”,因此每个元素的大小为4个字节:
ADD EBX, 4 ;What is this doing and how does it work, why would you add the number 4?
最后,除以“ [N]”:
DIV [N] ;Divide the result of the calculation
当值为“ dd”时,“ DIV”指令也会使用“ EDX”寄存器,因此最好清除“ EDX”以避免错误的结果:
MOV EDX, 0
DIV [N] ;Divide the result of the calculation
现在,“ EDX”为0,该除法将仅除以“ EAX”,并获得平均值。
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
...)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.