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

时间:2011-02-02 22:07:24

标签: assembly x86 intel deprecated instructions

我正在使用x86汇编语言编程类,并且知道不再使用某些指令 - 因为它们在现代处理器上很慢;例如,循环指令。

我无法找到任何被认为已弃用且应该避免的指令列表;任何指导都将不胜感激。

4 个答案:

答案 0 :(得分:9)

最好的办法是咨询Intel's official optimization guide

可以找到其他手册here

答案 1 :(得分:4)

哦,但是仍然有充分的理由使用loop指令。例如,loop label只需要两个字节。与dec cx后面跟jnz label相反,需要三个字节。有时代码大小比速度更重要。

但是,我建议,如果你只是学习x86汇编 - 特别是如果这是你第一次涉及汇编语言 - 你首先要集中精力去做事情。一旦你对事情的运作方式有了更好的了解,就会担心让它们变得更快。

答案 2 :(得分:2)

所有CPU指令都具有100%的功能,可以与旧CPU兼容。那么为什么要避免一些指令呢?没有真正弃用的x86指令!但我们可以说:

1) rep movsb 等所有字符串结构都较慢。

2) xlat 缓慢且极少使用。

3)堆栈帧功能 ENTER和LEAVE 的使用也很慢。

4)Uder Windows(XP,vista ...)不推荐使用的指令是IN和OUT,但仅在CPU环2(应用程序级别)下,不推荐使用 int nn ,但int3除外(调试器陷阱)。

编辑:在不同版本的CPU上添加了简单的速度测试以检查字符串指令rep cmp

在Delphi IDE下进行测试,但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.

ArraySize的测试结果= 50000

平均结果......

1)我的英特尔单核CPU Pentium 4结果:循环滴答: 232000 ; Rep ticks: 233000

2)我的英特尔酷睿2四核CPU结果:循环滴答: 158000 ; Rep ticks: 375000

答案 3 :(得分:1)

如果你知道要避免什么,直接去处理器制造商,intel和amd都有他们的处理器支持的指令集的手册以及他们支持它们的程度,如果可能是优化量,你最好的选择,但是如果你刚才刚刚开始,请听Jim的建议,在你担心速度之前先让事情先发挥作用