Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 如何理解下面的代码片段_Assembly_X86_Nasm_Microprocessors - Fatal编程技术网

Assembly 如何理解下面的代码片段

Assembly 如何理解下面的代码片段,assembly,x86,nasm,microprocessors,Assembly,X86,Nasm,Microprocessors,背景:由于在线课程,一些印度大学的计算机课程已经缩减为教师只给我们代码,并期望我们死记硬背 该程序用于计算给定数组中+ve和-ve个数 我的问题是从第45行到第59行(如下所示) 在上面的代码中,据我所知,我将数组的起始位置存储在ESI寄存器中,并扫描每个元素,检查它是否为正 但是,我如何知道何时到达数组的末尾 代码维护ECX寄存器,但不使用它。为什么这不是无休止地运行呢 是否也应该有某种带有DEC ECX和JE 0指令的循环 是否也应该有某种带有DEC ECX和JE 0指令的循环 这几乎就是所

背景:由于在线课程,一些印度大学的计算机课程已经缩减为教师只给我们代码,并期望我们死记硬背

该程序用于计算给定数组中+ve和-ve个数

我的问题是从第45行到第59行(如下所示)

在上面的代码中,据我所知,我将数组的起始位置存储在ESI寄存器中,并扫描每个元素,检查它是否为正

但是,我如何知道何时到达数组的末尾

代码维护ECX寄存器,但不使用它。为什么这不是无休止地运行呢

是否也应该有某种带有DEC ECX和JE 0指令的循环

是否也应该有某种带有DEC ECX和JE 0指令的循环


这几乎就是所做的。

循环下一个_num指令大致相当于
dec ecx;jnz next_num
。一个好的开始是在调试器中单步执行它以监视寄存器值的更改。如果
loop
改变了ECX这一事实让您感到惊讶,请查阅指令集参考手册。此外,这是一种测试符号位的低效方法<代码>测试eax,eax/
如果eax<0
(有符号比较),则jl阴性将是惯用的跳转方式。
jl
条件基于符号标志,无需将其旋转为进位。您甚至可以
cmp dword[esi],0
来比较内存操作数。还要注意,非负数包括零,这也不是正数。此外,无需更新循环内的两个计数器,只需使用
shr eax,31
/
添加ebx,eax
计算负数,并在最后计算
非负=总负
。不需要分支,逐字累加符号位。@Peter Cordes:test eax,eax之后,你也可以使用
js negative
,我发现这比使用
jl
@ecm:yup更清楚,符号位本身有分支的语义,而值小于零则有分支。(
jl
的语义更适合
cmp eax,0
;针对寄存器本身进行测试是
cmp
使用0的窥视孔优化,因此test/jl需要仔细考虑该语义,使其看起来自然。有趣的事实是:
cmp reg,0
//code>js,它可以将cmp与进行宏融合。)de>jl但不是
js
。即使核心2也可以融合
测试
/
js
,所以这两种习惯用法都可以)谢谢!我可能应该更多地阅读《英特尔开发人员手册》
mov    esi, arr
mov    ecx,arr_size         ;Array counter i.e. 6 
mov    ebx,0;                   ;counter for     +ve nos
mov    edx,0;                   ;counter for    -ve nos.

next_num:
    mov    eax,[esi]         ; take no. in RAX
    rcl    eax,1             ; rotate left 1 bit to check for sign bit
    jc    negative
positive:
    inc    ebx            ; no carry, so no. is +ve
    jmp    next
negative:
    inc    edx            ; carry, so no. is -ve
next:
    add  esi,4                ; 32 bit nos i.e. 4 bytes
    loop next_num