LOOP(英特尔参考手动输入)递减ecx/rcx,然后如果非零则跳转.这很慢,但是英特尔不能廉价地把它变得很快吗? dec/jnz已经将宏观融合成 Sandybridge家族的一个 uop; 唯一的区别是设置标志.
loop关于各种微体系结构,来自Agner Fog的说明表:
Bulldozer-family/Ryzen:1 m-op(与宏观融合测试和分支相同,或者jecxz)
P4:4次(相同jecxz)
loope/ loopne).吞吐量= 4c(loop)或7c(loope/ne).loope/ loopne). 吞吐量=每5个循环一个,这是将循环计数器保留在内存中的瓶颈!jecxz只有2 uops,吞吐量与普通吞吐量相同jcc难道解码器不能像lea rcx, [rcx-1]/ 那样解码jrcxz吗?这将是3 uops.至少那是没有地址大小前缀的情况,否则它必须使用ecx和截断RIP,EIP如果跳转; 也许奇怪的地址大小选择控制减量的宽度解释了许多uops?
或者更好,只需将其解码为不设置标志的融合分支和分支? dec ecx …
当我拆卸我的小功能时,我碰巧看到了这个电话
call 0xf60d2f47 <__i686.get_pc_thunk.bx>.
Run Code Online (Sandbox Code Playgroud)
我不知道为什么我需要在我的程序中调用此函数.任何解释都会有所帮助.
根据英特尔在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被称为通用目的?
谢谢你的帮助.
我目前正在学习一门课程,要求我编写汇编代码,准确地说是 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) 我正在处理一小段 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)