相关疑难解决方法(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
查看次数

什么是__i686.get_pc_thunk.bx?为什么我们需要这个电话?

当我拆卸我的小功能时,我碰巧看到了这个电话

call   0xf60d2f47 <__i686.get_pc_thunk.bx>.
Run Code Online (Sandbox Code Playgroud)

我不知道为什么我需要在我的程序中调用此函数.任何解释都会有所帮助.

c assembly glibc shared-libraries

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

为什么rbp和rsp称为通用寄存器?

根据英特尔在x64中,以下寄存器称为通用寄存器(RAX,RBX,RCX,RDX,RBP,RSI,RDI,RSP和R8-R15)https://software.intel.com/en-us/articles/介绍到x64组装.

在下面的文章中,写了RBP和RSP是专用寄存器(RBP指向当前堆栈帧的基础,RSP指向当前堆栈帧的顶部). https://www.recurse.com/blog/7-understanding-c-by-learning-assembly

现在我有两个相互矛盾的陈述.英特尔声明应该是值得信赖的,但是什么是正确的,为什么RBP和RSP被称为通用目的?

谢谢你的帮助.

assembly x86-64 cpu-registers

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

地址清理程序说存在段错误,但 valgrind 和 gdb 说没有?

我目前正在学习一门课程,要求我编写汇编代码,准确地说是 x86-64 AT&T 语法汇编代码。下面是 ac 文件,其中包含我必须编写其汇编代码的函数“bubble”的函数定义。

#include<stdio.h>
#include<stdlib.h>

void bubble(int* arr, int len);

int main(){
    int n;
    scanf("%d", &n);
    int* arr = malloc(sizeof(int)*n);
    for (int i = 0; i < n; i++)
    {
        scanf("%d", &arr[i]);
    }
    bubble(arr, n);
    for (int i = 0; i < n; i++)
    {
        printf("%d ", arr[i]);
    }
    printf("\n");
    free(arr);
}
Run Code Online (Sandbox Code Playgroud)

下面是函数 bubble 的汇编代码,

.global bubble
.text

bubble:
    movq $-1, %rcx
.L1:
    incq %rcx
    movl 4(%rdi,%rcx,4), %eax
    cmpl (%rdi,%rcx,4), %eax
    jge .T1
    movl (%rdi,%rcx,4), %eax
    movl …
Run Code Online (Sandbox Code Playgroud)

assembly gcc x86-64 segmentation-fault address-sanitizer

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

为什么使用 %ebx 寄存器会导致我的汇编代码出现分段错误

我正在处理一小段 i386 汇编代码,并在使用 %ebx 寄存器时遇到分段错误。我希望能了解一些关于为什么会发生这种情况的见解。

我有一个非常简单的汇编函数的两个版本。该函数的目的是将两个整数参数相加。当我使用 %ecx 寄存器时,该函数可以正常工作。但是,当我切换到使用 ebx 寄存器时,会导致分段错误。这是两个版本的代码:

版本 1(导致分段错误):

.globl addArgs
.text
addArgs:
    movl 4(%esp), %eax
    movl 8(%esp), %ebx
    addl %ebx, %eax
    ret
Run Code Online (Sandbox Code Playgroud)

我缺少有关 ebx 寄存器的特定信息吗?

所以下面的版本可以完美运行。

版本 2(工作正常):

.globl addArgs
.text
addArgs:
    movl 4(%esp), %eax
    movl 8(%esp), %ecx
    addl %ecx, %eax
    ret
Run Code Online (Sandbox Code Playgroud)

我正在 32 位 x86 系统上编译我的代码并使用 GCC 进行编译。

在这种情况下,下面是使用该函数的 C 代码:

#include <stdio.h>

int addArgs();

int main(){
    int a = 1, b = 2;
    printf("%d\n",  addArgs(a, b));
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这就是我编译它的方式:

.globl addArgs
.text
addArgs: …
Run Code Online (Sandbox Code Playgroud)

c x86 assembly cpu-registers calling-convention

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