Assembly 是否有不推荐使用的x86指令列表?

Assembly 是否有不推荐使用的x86指令列表?,assembly,x86,intel,deprecated,instructions,Assembly,X86,Intel,Deprecated,Instructions,我正在上x86汇编语言编程课,我知道某些指令不应该再被使用了——因为它们在现代处理器上速度很慢;例如,循环指令 我还没有找到任何被认为是不推荐的并且应该避免的指令列表;任何指导都将不胜感激。哦,但是仍然有很好的理由使用循环指令。例如,循环标签只需要两个字节。与dec cx后接jnz标签相反,需要三个字节。有时代码大小比速度更重要 然而,我建议,如果您只是在学习x86汇编语言——特别是如果这是您第一次涉足汇编语言——那么您首先应该专注于如何做事情。一旦你对事物的运行方式有了更好的了解,那么就要担心

我正在上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写入。