相关疑难解决方法(0)

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

如果我在循环中使用ECX,那么循环的正确方法是什么(汇编)

我目前正在学习汇编语言,我有一个输出"Hello World!"的程序.:

        section .text                                                                                    
        global _start                                                                                    
_start:                                                                                                                                                                                               
        mov ebx, 1                                                                                       
        mov ecx, string                                                                                  
        mov edx, string_len                                                                              
        mov eax, 4                                                                                      
        int 0x80                                                                                                                                                                          
        mov eax, 1                                                                                       
        int 0x80                                                                                         

        section .data                                                                                    
        string db "Hello World!", 10, 0                                                                  
        string_len equ $ - string
Run Code Online (Sandbox Code Playgroud)

我理解这段代码的工作原理.但是,现在,我希望显示10倍的线.我在互联网上看到的代码循环如下:

 mov ecx, 5
 start_loop:
 ; the code here would be executed 5 times
 loop start_loop
Run Code Online (Sandbox Code Playgroud)

问题:我试图在我的代码上实现循环,但它输出一个无限循环.我还注意到循环需要ECX和写入功能也需要ECX.显示10次"Hello World!"的正确方法是什么??

这是我当前的代码(产生无限循环):

        section .text                                                                                    
        global _start                                                                                    
_start:                                                                                                  
        mov ecx, 10                                                                                      
myloop:                                                                                                  
        mov ebx, 1 ;file descriptor                                                                                      
        mov ecx, string                                                                                 
        mov …
Run Code Online (Sandbox Code Playgroud)

x86 assembly loops

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

处理器可以同时进行内存和算术运算吗?

在汇编程序和处理程序的研究中,有一件事把我带出来,如何完成指令:

add mem, 1
Run Code Online (Sandbox Code Playgroud)

在我的脑海中,处理器无法加载内存值在同一指令期间处理算术运算.所以我觉得它发生在:

mov reg, mem
add reg, 1
mov mem, reg
Run Code Online (Sandbox Code Playgroud)

如果我考虑使用RISC Pipeline的处理器,我们可以观察一些停顿.对于简单的指令来说,这是令人惊讶的i++:

|  Fetch  | Decode  | Exec    | Memory  | WriteB  |
          |  Fetch  |         |         | Decode  | Exec    | Memory  | WriteB  |
                    |  Fetch  |         |         |         | Decode  | Exec    | Memory  | WriteB  |
Run Code Online (Sandbox Code Playgroud)

(正如我在Patterson的书" 计算机体系结构:定量方法"中所读到的,寄存器在解码 uOp,存储/加载到存储器uOp中读取,我们允许自己在存储器uOp中获取寄存器的值.)

我对吗?还是现代处理器有更具效的方法来做到这一点?

c assembly cpu-architecture risc

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

如何让BSR指令在64位上工作?

我正在尝试找到无符号 64 位 int 的前导位。我正在使用 BSR,因为我的处理器没有 LZCNT 指令。我的问题是,一旦输入正好是 2^32,它就会返回 2^64 作为前导位值,然后循环返回输出,直到 2^64。

这是我的代码:

unsigned long int LeadingBit(unsigned long int a) {
  if(a==0)
    return 0;
  unsigned long int nlb;
  asm (
       "BSR %1, %0   \n"
       : "=r" (nlb)
       : "mr" (a)
       : "cc"
       );
  return 1<<nlb;

}
Run Code Online (Sandbox Code Playgroud)

这段代码的目的是能够输入一个64位整数,并让它返回前导1的位置的值。例如:a = 65(1000001)返回1000000。

assembly g++ x86-64 inline-assembly

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

NASM与CMP和OR之间的区别

我有两个问题.第一个:'或'与'cmp'有什么区别?我已经看过了两个,看起来他们做了同样的事情.我的第二个问题:做什么

or al, al
Run Code Online (Sandbox Code Playgroud)

意思?它不应该一直返回真(如x == x)吗?

assembly nasm

3
推荐指数
1
解决办法
3479
查看次数

实际的 Intel x86 处理器有多少开销才能进行流水线操作?

在我毕业的计算机架构上,教授谈到了 MIPS 中的流水线,但也说由于 x86 指令集的某些情况(我不太记得了),x86 处理器需要有一个额外的逻辑来预处理组装指令和管道。

我不是在寻找直接的数字答案,而不是寻找有关该主题的文档或提示:正在做什么来翻译 x86 指令以允许流水线操作,此逻辑如何工作等。

谢谢一堆。

x86 assembly mips pipelining

3
推荐指数
1
解决办法
1680
查看次数

在x86-64多核机器上读取和写入C++ Atomic中的int

我读过这个,我的问题很相似但有点不同.

注意,我知道C++ 0x并不能保证这一点,但我特别要求像x86-64这样的多核机器.

假设我们有2个线程(固定到2个物理内核)运行以下代码:

// I know people may delcare volatile useless, but here I do NOT care memory reordering nor synchronization/
// I just want to suppress complier optimization of using register.
volatile int n; 

void thread1() {
    for (;;)
        n = 0xABCD1234;
        // NOTE, I know ++n is not atomic,
        // but I do NOT care here.
        // what I cares is whether n can be 0x00001234, i.e. in the middle of the update from core-1's …
Run Code Online (Sandbox Code Playgroud)

c++ multithreading atomic cpu-cache

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

为什么使用 push/pop 而不是 sub 和 mov?

当我在https://godbolt.org上使用不同的编译器时,我注意到编译器生成这样的代码是很常见的:

push    rax
push    rbx
push    rcx
call    rdx
pop     rcx
pop     rbx
pop     rax
Run Code Online (Sandbox Code Playgroud)

我理解每个pushpop做两件事:

  1. 将操作数移入/移出堆栈空间
  2. 递增/递减堆栈指针 (rsp)

所以在我们上面的例子中,我假设 CPU 实际上在做 12 次操作(6 次移动,6 次加/减),不包括call. 组合添加/订阅不是更有效吗?例如:

sub rsp, 24
mov [rsp-24], rax
mov [rsp-16], rbx
mov [rsp-8], rcx
call    rdx
mov rcx, [rsp-8]
mov rbx, [rsp-16]
mov rax, [rsp-24]
add rsp, 24
Run Code Online (Sandbox Code Playgroud)

现在只有 8 次操作(6 次移动,2 次加/减),不包括call. 为什么编译器不使用这种方法?

x86 assembly x86-64 cpu-architecture micro-optimization

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

在内存位置调用 `add` 是否比在寄存器上调用它然后移动值更快?

什么更快:

add DWORD PTR [rbp-0x4],1
Run Code Online (Sandbox Code Playgroud)

或者

 mov    eax,DWORD PTR [rbp-0x4]
 add    eax,1
 mov    DWORD PTR [rbp-0x4],eax
Run Code Online (Sandbox Code Playgroud)

我已经看到编译器生成的第二个代码,所以也许调用add寄存器要快得多?

x86 assembly x86-64 micro-optimization

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

逻辑/算术移位更少的位更快吗?

x>>2不是更快x>>31?换句话说,sar x, 2sar x, 31? 我做了一些简单的测试,它们似乎具有相同的速度。我将不胜感激任何确凿的证据。

c++ performance x86 assembly cpu-architecture

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