我目前正在学习x86汇编语言,并想知道什么是实现循环的更好方法。一种方法是将一个值传递给ecx寄存器并使用循环指令,另一种方式是使用jmp指令,然后进入循环体,然后有条件跳转到循环体的开始处。我想第一个会有更好的可读性,但其他的我不知道为什么要使用它。x86汇编编程循环与ecx和循环指令与jmp + j <condition>
回答
当您提到jmp + body + test时,我相信您正在讨论高级语言中while
循环的翻译。第二种方法是有原因的。让我们来看看。
考虑
x = N
while (x != 0) {
BODY
x--
}
用简单的方式是
mov ecx, N ; store var x in ecx register
top:
cmp ecx, 0 ; test at top of loop
je bottom ; loop exit when while condition false
BODY
dec ecx
jmp top
bottom:
这有N个条件跳转和N无条件跳跃。
第二种方式是:
mov ecx, N
jmp bottom
top:
BODY
dec ecx
bottom:
cmp ecx, 0
jne top
现在我们还在做ň条件跳转,但我们只能做一件无条件跳转。节省很少,但它可能很重要,特别是因为它在循环中。
现在你没有提到的loop
指令,它本质上是
dec ecx
cmp ecx, 0
je somewhere
你将如何工作,在?大概是这个样子:
mov ecx, N
cmp ecx, 0 ; Must guard against N==0
je bottom
top:
BODY
loop top ; built-in dec, test, and jump if not zero
bottom:
这是典型的CISC处理器的一个漂亮的小的解决方案。它比上面的第二种方法更快吗?这在很大程度上取决于架构。如果您真的想了解更多信息,我建议您对IA-32和Intel 64处理器架构中的loop
指令的性能进行一些研究。
谢谢,这有助于退出,我会尝试做一些关于ECX循环速度的进一步研究:) – rob
@rob,快乐的研究。我可以建议http://www.agner.org/optimize/optimizing_assembly.pdf?一个惊人的资源。很长。在第89页提到,你应该避免JECXZ和LOOP,因为它们在更现代的体系结构上效率不高。 –
相关:[为什么循环指令很慢?英特尔能否有效地实现它?](https://stackoverflow.com/questions/35742570/why-is-the-loop-instruction-slow-couldnt-intel-have-implemented-it-efficiently)一些历史因素。有趣的事实:AMD推土机/ Ryzen拥有快速的“循环”,但没有其他任何事情。还有相关的问题:[为什么循环总是像这样编译?](https://stackoverflow.com/questions/47783926/why-are-loops-always-compiled-like-this)以获得高效的循环结构:如您所说,有条件底部的分支,以及可能需要运行0次的各种策略。 –
- 1. 汇编 - 循环结尾的子指令
- 2. 汇编语言循环
- 3. 对于循环和穿过x86中的数组汇编代码
- 4. 汇编程序中的无限循环
- 5. 循环引用和低级汇编
- 6. MIPS汇编简单for循环
- 7. Stata编程和putexcel循环
- 8. 如何在x86汇编语言中创建一个循环?
- 9. 循环/输入逻辑流问题(NASM x86汇编)
- 10. 英特尔x86汇编中的循环永远持续
- 11. 从汇编x86中的JMP返回?
- 12. 与循环
- 13. PHP与循环内循环
- 14. 通过阵列循环MIPS汇编
- 15. R编程循环差异
- 16. 嵌套循环与编译指示omp并行为,jumbling up
- 17. 优化x64汇编器MUL循环
- 18. 嵌套循环汇编代码
- 19. 如何在汇编语言中循环
- 20. 内部循环中的内联汇编
- 21. 在ARM汇编中开发循环
- 22. 创建与循环
- 23. 使用C++函数编译循环汇编程序
- 24. 循环组件x86
- 25. Java编程 - 循环链表
- 26. Python编程无意循环
- 27. 循环中的Java编程
- 28. 停止编程循环
- 29. 批处理编程循环?
- 30. 简单的循环编程
从来不知道/知道什么时候接受它,因为我总是可能会有更好的答案?这真的很重要吗?因为我真的不知道。 – rob
相关:[为什么总是像这样编译循环?](https://stackoverflow.com/questions/47783926/why-are-loops-always-compiled-like-this):几乎总是最好使用'do {} while()'在asm中构造,底部有条件分支。如果循环可能需要运行0次,那么jmp到底是一种策略,但通常不是最好的。 –