我目前正在学习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. 在x86汇编中的循环
- 3. 双条件While循环在x86汇编
- 4. 汇编循环和可变
- 5. J编程初学者循环
- 6. 汇编中的循环
- 7. MIPS汇编代码循环
- 8. 汇编代码 - 循环
- 9. 汇编语言循环
- 10. 汇编语言:反循环
- 11. 如何在x86汇编语言中创建嵌套循环
- 12. 对于循环和穿过x86中的数组汇编代码
- 13. 汇编程序中的无限循环
- 14. 加快x64汇编程序ADD循环
- 15. 汇编程序卡在sys_read循环中
- 16. 循环引用和低级汇编
- 17. MIPS汇编简单for循环
- 18. 汇编语言中的嵌套循环
- 19. C++编程循环总和
- 20. Stata编程和putexcel循环
- 21. 与JMP指令
- 22. c#编程循环
- 23. Python编程循环
- 24. C编程循环
- 25. 从汇编x86中的JMP返回?
- 26. 循环/输入逻辑流问题(NASM x86汇编)
- 27. 英特尔x86汇编中的循环永远持续
- 28. 如何在x86汇编语言中创建一个循环?
- 29. 定义许多角指令与循环
- 30. AngularJS指令与循环依赖关系
从来不知道/知道什么时候接受它,因为我总是可能会有更好的答案?这真的很重要吗?因为我真的不知道。 – rob
相关:[为什么总是像这样编译循环?](https://stackoverflow.com/questions/47783926/why-are-loops-always-compiled-like-this):几乎总是最好使用'do {} while()'在asm中构造,底部有条件分支。如果循环可能需要运行0次,那么jmp到底是一种策略,但通常不是最好的。 –