相关疑难解决方法(0)

为什么循环指令慢?英特尔无法有效实施吗?

LOOP(英特尔参考手动输入)递减ecx/rcx,然后如果非零则跳转.这很慢,但是英特尔不能廉价地把它变得很快吗? dec/jnz已经将宏观融合成 Sandybridge家族的一个 uop; 唯一的区别是设置标志.

loop关于各种微体系结构,来自Agner Fog的说明表:

  • K8/K10:7 m-ops
  • Bulldozer-family/Ryzen:1 m-op(与宏观融合测试和分支相同,或者jecxz)

  • P4:4次(相同jecxz)

  • P6(PII/PIII):8次
  • Pentium M,Core2:11 uops
  • Nehalem:6个uops.(11为loope/ loopne).吞吐量= 4c(loop)或7c(loope/ne).
  • SnB家族:7个uops.(11为loope/ loopne). 吞吐量=每5个循环一个,这是将循环计数器保留在内存中的瓶颈!jecxz只有2 uops,吞吐量与普通吞吐量相同jcc
  • Silvermont:7次
  • AMD Jaguar(低功耗):8 uops,5c吞吐量
  • 通过Nano3000:2 uops

难道解码器不能像lea rcx, [rcx-1]/ 那样解码jrcxz吗?这将是3 uops.至少那是没有地址大小前缀的情况,否则它必须使用ecx和截断RIP,EIP如果跳转; 也许奇怪的地址大小选择控制减量的宽度解释了许多uops?

或者更好,只需将其解码为不设置标志的融合分支和分支? dec ecx …

performance x86 assembly intel cpu-architecture

53
推荐指数
3
解决办法
6096
查看次数

在某些CPU的紧密循环中出现ADC/SBB和INC/DEC问题

我在Delphi中编写一个简单的BigInteger类型.它主要由TLimb的动态数组组成,其中TLimb是32位无符号整数,32位大小字段,它还保存BigInteger的符号位.

要添加两个BigIntegers,我创建一个适当大小的新BigInteger然后,在一些簿记之后,调用以下过程,将三个指针传递给左右操作数和结果的数组的相应开始,以及左右肢的数量分别为.

普通代码:

class procedure BigInteger.PlainAdd(Left, Right, Result: PLimb; LSize, RSize: Integer); 
asm
// EAX = Left, EDX = Right, ECX = Result
        PUSH    ESI
        PUSH    EDI
        PUSH    EBX
        MOV     ESI,EAX                 // Left
        MOV     EDI,EDX                 // Right
        MOV     EBX,ECX                 // Result
        MOV     ECX,RSize               // Number of limbs at Left
        MOV     EDX,LSize               // Number of limbs at Right
        CMP     EDX,ECX
        JAE     @SkipSwap
        XCHG    ECX,EDX                 // Left and LSize should be largest
        XCHG    ESI,EDI                 // so swap
@SkipSwap:
        SUB     EDX,ECX                 // …
Run Code Online (Sandbox Code Playgroud)

delphi x86 assembly

15
推荐指数
2
解决办法
919
查看次数

装配x86中的斐波那契系列

经过长时间的无数错误之后,希望这是最后的错误.

没有编译或运行时错误,只是一个逻辑错误.

编辑:(固定伪码)

我的伪代码:

first  = 1;
second = 1;
third  = 0;

 for i from 1 to n{

    third=first+second
    first=second
    second=third

}
return third
Run Code Online (Sandbox Code Playgroud)

这将打印该系列的最终结果.

我的汇编代码:

我尽可能地添加了评论

.386
.model flat,stdcall
option casemap:none

.data
timestell     db "Loop Ran : %d Times -----",0     ;format string
fmtd   db "%d",0
finalprint  db "Final Number is : %d ------",0     ;format string
times  dd 0Ah                                      ;times to loop
first dd 1h
second dd 1h
third dd 0h


.data?

retvalue1 dd ?             ;we will initialize it …
Run Code Online (Sandbox Code Playgroud)

x86 assembly fibonacci

7
推荐指数
1
解决办法
3734
查看次数

x86_64 - 汇编 - 循环条件和乱序

不是要求基准.

(如果是这样的话,我会自己做的.)


我的问题:

为方便起见,我倾向于避免间接/索引寻址模式.

作为替代,我经常使用立即,绝对或寄存器寻址.

代码:

; %esi has the array address. Say we iterate a doubleword (4bytes) array.
; %ecx is the array elements count
(0x98767) myloop:
    ... ;do whatever with %esi
    add $4, %esi
    dec %ecx
    jnz 0x98767;
Run Code Online (Sandbox Code Playgroud)

在这里,我们有一个序列化的组合(dec和jnz),它可以防止正常的乱序执行(依赖).

有没有办法避免/破坏dep?(我不是装配专家).

assembly loops x86-64 conditional-statements

4
推荐指数
1
解决办法
1070
查看次数

有没有办法增加xmm寄存器的值?

我想知道,有没有办法在xmm寄存器中增加一个值,或者你只能将一个值移动到一个?

我的意思是,你可以这样做:

inc eax
Run Code Online (Sandbox Code Playgroud)

或者像这样:

inc [ebp+7F00F000]
Run Code Online (Sandbox Code Playgroud)

有没有办法用xmm做同样的事情?

我尝试过类似的东西,但......它不起作用

  inc [rbx+08]
  movss xmm1,[rbx+08]
Run Code Online (Sandbox Code Playgroud)

我甚至尝试过一些非常愚蠢的东西,但它也没有用

push edx
pextrw edx,xmm2,0
add edx,1
mov [rbx+08],edx
movss xmm1,[rbx+08]
pop edx
Run Code Online (Sandbox Code Playgroud)

x86 assembly sse add

2
推荐指数
1
解决办法
1267
查看次数

如何使用静态数组的结束指针作为循环条件来比较 x86 中的地址?

从头开始编程的挑战之一是“修改程序以使用结束地址而不是数字 0 来知道何时停止。”

\n

我发现很难做到这一点,因为到目前为止,这本书只介绍了movl,,cmplincl以及寻址模式)和jmp指令。基本上,下面的代码片段中的所有内容都是到目前为止所介绍的。我发现的所有解决方案都涉及本书中尚未介绍的说明。下面的代码查找集合中的最大值。

\n
.section .data\ndata_items:             #These are the data items\n.long 3,67,34,222,45,75,54,34,44,33,22,11,66,0\n\n.section .text\n.globl _start\n_start:\n    movl $0, %edi                   # move 0 into the index register\n    movl data_items(,%edi,4), %eax  # load the first byte of data\n    movl %eax, %ebx                 # since this is the first item, %eax is\n                                    # the biggest\nstart_loop:                     # start loop\n    cmpl $0, %eax                   # check to see if we\xe2\x80\x99ve hit the end\n    je loop_exit\n    incl %edi                       # …
Run Code Online (Sandbox Code Playgroud)

linux x86 assembly pointers att

2
推荐指数
1
解决办法
278
查看次数

X86斐波那契计划

我的任务是编写一个程序来计算斐波那契数列的前七个值.给出的公式是:

Fib(1) = 1, Fib(2) = 1, Fib(n) = Fib(n-1) + Fib(n-2)
Run Code Online (Sandbox Code Playgroud)

我相信这是一个功能,但我不明白如何将其合并到代码中.我需要将值放在EAX寄存器中.我使用MASM并没有任何区别.任何提示?

x86 assembly masm

-2
推荐指数
1
解决办法
6306
查看次数