13

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

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

4

4 回答 4

9

最好的办法是查阅英特尔的官方优化指南

可以在此处找到其他手册。

于 2011-02-03T13:17:32.840 回答
4

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

但是,我建议,如果您只是学习 x86 汇编——特别是如果这是您第一次涉足汇编语言,那么您首先要专注于如何做事。一旦你对事情的运作方式有了更好的了解,然后担心让它们变得更快。

于 2011-02-02T22:25:12.367 回答
2

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

1)所有像rep movsb这样的字符串指令都比较慢。

2) xlat很慢而且很少使用。

3) 栈帧函数ENTER 和 LEAVE的使用也很慢。

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

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

测试是在 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) 我的 Intel 单核 CPU Pentium 4 结果: Loop ticks : 232000;代表滴答数:233000

2)我的 Intel Core 2 Quad CPU 结果: Loop ticks : 158000 ; 代表嘀嗒:375000

于 2011-02-03T09:27:45.770 回答
1

如果您知道要避免什么,请直接联系处理器制造商,英特尔和 AMD 都有关于其处理器支持的指令集以及它们支持的程度的手册,如果可能是优化量,您最好的选择,但如果您只有刚开始,听从吉姆的建议,在担心速度之前先把事情做好

于 2011-02-03T04:12:38.700 回答