相关疑难解决方法(0)

XOR寄存器,寄存器(汇编程序)

我们不时要分析汇编程序代码(IA32),而且我经常会遇到如下所示的指令:

xor ax, ax
Run Code Online (Sandbox Code Playgroud)

或与其他寄存器藏汉:xor dx, dx,xor al, al,...

这到底是做什么的?(ax xor ax总是给0?)

x86 assembly xor

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

装配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
查看次数

go编译器生成的汇编代码中的这种模式是什么?

我在Linux内核中调试了一个无关紧要的问题,看到由主管管理的etcd进程反复出现页面错误异常并接收到SIGSEGV.

我好奇并使用objdump来反汇编程序,并发现错误的amd64指令是:

89 04 25 00 00 00 00    mov    %eax,0x0
Run Code Online (Sandbox Code Playgroud)

然后我看了一个hello world程序的反汇编.我在go编译器生成的代码中看到了一个非常常见的模式,即在函数结束时ret,mov紧接着,然后jmp返回函数.例如,

0000000000400c00 <main.main>:
  400c00:       64 48 8b 0c 25 f0 ff    mov    %fs:0xfffffffffffffff0,%rcx
  400c07:       ff ff
        ...
  400c4b:       48 83 7c 24 48 00       cmpq   $0x0,0x48(%rsp)
  400c51:       74 59                   je     400cac <main.main+0xac>
  400c53:       48 c7 04 24 c0 fc 47    movq   $0x47fcc0,(%rsp)
  400c5a:       00

        ...
  400cab:       c3                      retq
  400cac:       89 04 25 00 00 00 00    mov    %eax,0x0
  400cb3:       eb …
Run Code Online (Sandbox Code Playgroud)

assembly go

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

程序集cltq和movslq的区别

计算机系统的第3章程序员的观点(第2版)提到了
cltq相当于movslq %eax, %rax.

为什么他们创建一个新的指令(cltq)而不是仅使用movslq %eax,%rax?这不是多余的吗?

x86 assembly x86-64 instruction-set att

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

为什么VC++ 2010经常使用ebx作为"零寄存器"?

昨天我看了VC++ 2010生成的一些32位代码(很可能;不知道具体的选项,对不起),我对一个奇怪的反复出现的细节很感兴趣:在许多功能中,它ebx在序言中归零,它总是像"零寄存器"一样使用它(想想$zeroMIPS).特别是,经常:

  • 用它来清零记忆; 这并不罕见,因为a的编码mov mem,imm大于1到4个字节mov mem,reg(即使对于0也必须编码完整的立即值大小),但通常(gcc)必要的寄存器被"按需"清零,并保持不变为了更有用的目的;
  • 用它来比较零 - 比如cmp reg,ebx.这就是让我感到非常不寻常的事情,因为它应该完全相同test reg,reg,但是增加了对额外寄存器的依赖.现在,请记住,这发生在非叶子函数中,ebx经常被(被调用者)推入堆栈,因此我不相信这种依赖总是完全免费的.此外,它用于test reg,reg在完全相同的方式(test/ cmp=> jg).

最重要的是,"经典"x86上的寄存器是一种稀缺资源,如果你开始泄漏寄存器,你会浪费很多时间没有充分的理由; 为什么要浪费一个通过所有的功能只是为了保持零?(仍然,考虑一下,我不记得在使用这种"零寄存器"模式的函数中看到很多寄存器溢出).

那么:我错过了什么?它是一个编译器blooper还是一些令人难以置信的智能优化,在2010年特别有趣?

这是一段摘录:

    ; standard prologue: ebp/esp, SEH, overflow protection, ... then:
    xor     ebx, ebx
    mov     [ebp+4], ebx        ; zero out some locals
    mov     [ebp], ebx
    call    function_1
    xor     ecx, ecx            ; ebx _not_ used to zero registers
    cmp     eax, ebx            ; ... …
Run Code Online (Sandbox Code Playgroud)

x86 assembly visual-c++ visual-c++-2010

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

在Knights Landing上清除单个或几个ZMM寄存器的最有效方法是什么?

说,我想清除4个zmm寄存器.

以下代码是否会提供最快的速度?

vpxorq  zmm0, zmm0, zmm0
vpxorq  zmm1, zmm1, zmm1
vpxorq  zmm2, zmm2, zmm2
vpxorq  zmm3, zmm3, zmm3
Run Code Online (Sandbox Code Playgroud)

在AVX2上,如果我想清除ymm寄存器,vpxor比vxorps更快,速度更快,因为vpxor可以在多个单元上运行.

在AVX512上,我们没有用于zmm寄存器的vpxor,只有vpxorq和vpxord.这是清除寄存器的有效方法吗?当我使用vpxorq清除zmm寄存器时,CPU是否足够智能,不会对zmm寄存器的先前值产生错误依赖?

在没有物理AVX512 CPU测试的情况下 - 也许有人在Knights Landing上测试过?是否有任何延迟发布?

assembly avx xeon-phi avx512 knights-landing

7
推荐指数
2
解决办法
886
查看次数

在 x86 中设置和清除零标志

在 x86-64 中设置和清除零标志 (ZF) 的最有效方法是什么?

无需具有已知值的寄存器或根本没有任何空闲寄存器即可工作的方法是首选,但如果在这些或其他假设为真时有更好的方法可用,则也值得一提。

performance x86 assembly x86-64 micro-optimization

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

xorps在同一个寄存器上的目的是什么?

我正在查看以下反汇编的c ++代码

    auto test2 = convert<years, weeks>(2.0);
00007FF6D6475ECC  mov         eax,16Dh  
00007FF6D6475ED1  xorps       xmm1,xmm1  
00007FF6D6475ED4  cvtsi2sd    xmm1,rax  
00007FF6D6475ED9  mulsd       xmm1,mmword ptr [__real@4000000000000000 (07FF6D64AFE38h)]  
00007FF6D6475EE1  divsd       xmm1,mmword ptr [__real@401c000000000000 (07FF6D64AFE58h)] 
Run Code Online (Sandbox Code Playgroud)

并且很好奇xorps xmm1, xmm1教学的重点是什么.似乎任何数字xor本身只会给0?如果是这样,清除登记册的目的是什么?

注意:我只是出于纯粹的好奇而问这个问题.我对汇编语言知之甚少.

c++ assembly

6
推荐指数
1
解决办法
1605
查看次数

C++ 11:memory_order_relaxed和memory_order_consume之间的区别

我现在正在学习C++ 11内存阶模型,并想明白之间的差别memory_order_relaxedmemory_order_consume.

具体而言,我正在寻找一个简单的例子,其中一个不能代替memory_order_consumememory_order_relaxed.

有一篇很好的文章详细阐述了一个memory_order_consume可以应用的简单但非常具有说明性的例子.下面是文字复制粘贴.

例:

atomic<int*> Guard(nullptr);
int Payload = 0;
Run Code Online (Sandbox Code Playgroud)

制片人:

Payload = 42;
Guard.store(&Payload, memory_order_release);
Run Code Online (Sandbox Code Playgroud)

消费者:

g = Guard.load(memory_order_consume);
if (g != nullptr)
    p = *g;
Run Code Online (Sandbox Code Playgroud)

我的问题包括两部分:

  1. 一个可取代memory_order_consumememory_order_relaxed在上面的例子?
  2. 一个可以建议类似的例子memory_order_consume不能被替换memory_order_relaxed

c++ memory-model c++11

6
推荐指数
2
解决办法
2746
查看次数

最小操作码大小 x86-64 strlen 实现

我正在研究我的代码高尔夫/二进制可执行文件的最小操作码大小x86-64 strlen实现,该实现不应该超过某个大小(为了简单起见,请考虑演示场景)。
一般想法来自这里,大小优化想法来自这里这里

输入字符串地址在rdi,最大长度不大于Int32

xor   eax,eax ; 2 bytes
or    ecx,-1  ; 3 bytes
repne scasb   ; 2 bytes
not   ecx     ; 2 bytes
dec   ecx     ; 2 bytes
Run Code Online (Sandbox Code Playgroud)

最终结果是ecx11字节总数。

问题是关于设置ecx-1

选项 1 已经说明

or ecx,-1 ; 3 bytes
Run Code Online (Sandbox Code Playgroud)

选项 2

lea ecx,[rax-1] ; 3 bytes 
Run Code Online (Sandbox Code Playgroud)

选项 3

stc         ; 1 byte
sbb ecx,ecx ; 2 bytes
Run Code Online (Sandbox Code Playgroud)

选项 4 ,可能是最慢的一个

push -1 …
Run Code Online (Sandbox Code Playgroud)

assembly x86-64 nasm yasm

6
推荐指数
1
解决办法
1012
查看次数