Assembly 是否有不推荐使用的x86指令列表?
我正在上x86汇编语言编程课,我知道某些指令不应该再被使用了——因为它们在现代处理器上速度很慢;例如,循环指令Assembly 是否有不推荐使用的x86指令列表?,assembly,x86,intel,deprecated,instructions,Assembly,X86,Intel,Deprecated,Instructions,我正在上x86汇编语言编程课,我知道某些指令不应该再被使用了——因为它们在现代处理器上速度很慢;例如,循环指令 我还没有找到任何被认为是不推荐的并且应该避免的指令列表;任何指导都将不胜感激。哦,但是仍然有很好的理由使用循环指令。例如,循环标签只需要两个字节。与dec cx后接jnz标签相反,需要三个字节。有时代码大小比速度更重要 然而,我建议,如果您只是在学习x86汇编语言——特别是如果这是您第一次涉足汇编语言——那么您首先应该专注于如何做事情。一旦你对事物的运行方式有了更好的了解,那么就要担心
我还没有找到任何被认为是不推荐的并且应该避免的指令列表;任何指导都将不胜感激。哦,但是仍然有很好的理由使用
循环
指令。例如,循环标签
只需要两个字节。与dec cx
后接jnz标签
相反,需要三个字节。有时代码大小比速度更重要
然而,我建议,如果您只是在学习x86汇编语言——特别是如果这是您第一次涉足汇编语言——那么您首先应该专注于如何做事情。一旦你对事物的运行方式有了更好的了解,那么就要担心如何使它们更快。如果你想知道应该避免什么,直接去找处理器制造商,英特尔和amd都有关于它们的处理器支持的指令集的手册,以及它们支持它们的程度,如果可能是优化卷,但是,如果您只是刚刚开始,请接受Jim的建议,在您担心速度之前先让它工作起来所有CPU指令都是100%功能性的,以达到与旧CPU的兼容性。那么,为什么要避免一些指导呢?没有真正不推荐的x86指令!但我们可以说: 1) 所有字符串指令,如rep movsb都比较慢 2) xlat使用速度慢且非常罕见 3) 此外,堆栈帧函数的使用速度也很慢 4) Uder Windows(XP、vista…)不推荐使用的指令有输入和输出,但仅在CPU环2(应用级别)下,除int3(调试器陷阱)外,int nn也不推荐使用 编辑:添加了简单的速度测试来检查不同版本CPU上的字符串指令
rep cmp
。
测试是在DelphiIDE下进行的,但是asm部分很容易在任何其他IDE中翻译
program ProjectTest;
{$APPTYPE CONSOLE}
uses SysUtils, windows;
const
ArraySize = 50000;
var
StartTicks :int64;
EndTicks :int64;
arA :array [0..ArraySize - 1]of byte;
arB :array [0..ArraySize - 1]of byte;
begin
FillChar(ArA, SizeOf(ArA), 255); //Set all bytes to 0xFF
FillChar(ArB, SizeOf(ArB), 255); //Set all bytes to 0xFF
repeat
Sleep(100); //Calm down
asm
//Save StartTicks
rdtsc
mov dword ptr [StartTicks], eax
mov dword ptr [StartTicks + 4], edx
//Test LOOP
push edi
mov ecx, -ArraySize
mov edi, offset arA + ArraySize
mov esi, offset arB + ArraySize
@loop:
mov al,[esi + ecx]
cmp [edi + ecx], al
jnz @exit
inc ecx
jnz @loop
@exit:
pop edi
//Save EndTicks
rdtsc
mov dword ptr [EndTicks], eax
mov dword ptr [EndTicks + 4], edx
end;
WriteLn('Loop ticks : ' + IntToStr(EndTicks - StartTicks));
Sleep(100); //Calm down
asm
//Save StartTicks
rdtsc
mov dword ptr [StartTicks], eax
mov dword ptr [StartTicks + 4], edx
//Test REP
push edi
cld
mov ecx, ArraySize
mov edi, offset arA
mov esi, offset arB
repe cmpsb
pop edi
//Save EndTicks
rdtsc
mov dword ptr [EndTicks], eax
mov dword ptr [EndTicks + 4], edx
end;
WriteLn('Rep ticks : ' + IntToStr(EndTicks - StartTicks));
ReadLn //Wait keyboard
until false;
end.
阵列尺寸测试=50000
平均结果
1) 我的英特尔单核CPU奔腾4结果:循环滴答声:232000;代表勾号:233000
2) 我的Intel Core 2四CPU结果:循环滴答声:158000;代表滴答:375000您最好的选择是咨询
这是其他手册。基本上所有复杂的说明都比简单的慢。虽然从技术上讲x86是CISC,但将其用作RISC更快。@ruslik:这不一定是真的。如果您有一条执行与一组简单指令相同功能的复杂指令,那么使用专用指令可能会获得更好的性能。它更有可能被优化,甚至可能有专用的硬件,而您只使用简单的指令就可能错过这些硬件。@Nathan Fellman,关于这一点,我想到了
enter
/leave
指令之类的情况。然而,我想不出任何复杂指令比简单指令更快的情况。你能给我举几个例子让我更了解情况吗?你找不到一个列表,因为它们从来都不是“不推荐的”。。。根据CPU体系结构的不同,您在特定情况下使用的处理器会有所不同。另外,有些在某些情况下不可用,但它们仍然没有被弃用……至少可以说,这些细节非常依赖于CPU。你所写的对某些CPU来说是非常真实的,而对其他CPU来说是非常不真实的。同意。。。此详细信息适用于采用内置超线程技术的较新英特尔CPU。@GJ,您提到“所有字符串指令”[sic]速度较慢。比什么慢?此外,您确定除了int 3
之外,所有int nn
样式的指令都已弃用吗?单步中断int1
怎么样?rep-sto
/rep-mov
在英特尔CPU上速度很快。对于大于128B的memset/memcpy,当与对齐输入一起使用时,它们可以击败任何SSE或AVX环路。对于IvyBridge和更高版本,ERMSB功能尤其如此(这使得rep stosb
成为最佳选择,而不是rep stosq
然后清理)repe
/repne
compare/search指令不是特别快,你可以用一个很好的例子把它们打爆。《英特尔优化手册》中有一章介绍了memset/memcpy,以及它们的优化SSE实现(从其高性能库中)与rep mov
,适用于各种尺寸和路线。不要将rep MOV
与repe CMP
混为一谈rep mov
可以使用存储,避免缓存未命中时的所有权读取开销,但不会从缓存中逐出写入的数据。(对于SSE,您必须选择常规存储(对于大缓冲区更糟糕)而不是movnt
存储(对于小缓冲区更糟糕,因为它会从缓存中逐出写入的行)。)这正是我要找的文档类型!谢谢。另请参阅以获取优化资源的链接,特别是Agner Fog的优秀指南和insn表。dec cx
或dec rcx
对于asm初学者可能需要更多32位或64位模式的字节,从而最大限度地减少指令数量,尤其是分支数量,这是提高效率的合理近似值。我经常看到初学者问题有大量分支(例如,比较和分支,然后无条件分支到其他地方,甚至jmp-label
/label:
跳过块之间的空行…)。我想把树枝想成是不是掉下来需要练习。诚然,试图编写代码以避免AMD和Intel CPU上的陷阱是很困难的。但请参阅insn表和uarch写入。