小编Pet*_*des的帖子

'asm','__ asm'和'__asm__'有什么区别?

据我所知道的,唯一的区别__asm { ... };,并__asm__("...");是第一个使用mov eax, var第二个使用movl %0, %%eax:"=r" (var)结尾.还有什么其他差异?那又怎么样asm

c assembly gcc inline-assembly visual-c++

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

C hello世界的汇编输出的每一行的含义是什么?

我在这上面运行了gcc -S:

int main()
{
printf ("Hello world!");
}
Run Code Online (Sandbox Code Playgroud)

我得到了这个汇编代码:

        .file   "test.c"
        .section        .rodata
.LC0:
        .string "Hello world!"
        .text
.globl main
        .type   main, @function
main:
        leal    4(%esp), %ecx
        andl    $-16, %esp
        pushl   -4(%ecx)
        pushl   %ebp
        movl    %esp, %ebp
        pushl   %ecx
        subl    $20, %esp
        movl    $.LC0, (%esp)
        call    printf
        addl    $20, %esp
        popl    %ecx
        popl    %ebp
        leal    -4(%ecx), %esp
        ret
        .size   main, .-main
        .ident  "GCC: (GNU) 4.3.0 20080428 (Red Hat 4.3.0-8)"
        .section        .note.GNU-stack,"",@progbits
Run Code Online (Sandbox Code Playgroud)

我很想知道这个输出.有人可以在理解这个输出时分享一些指示,或者如果有人可以针对这些行/行组中的每一行标记注释来解释它的作用,那将会很棒.

linux x86 assembly gcc

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

数组初始化优化

编译以下代码片段时(clang x86-64 -O3

std::array<int, 5> test()
{
    std::array<int, 5> values {{0, 1, 2, 3, 4}};
    return values;
}
Run Code Online (Sandbox Code Playgroud)

它产生了我期望的典型装配

test():                               # @test()
        mov     rax, rdi
        mov     ecx, dword ptr [rip + .L__const.test().values+16]
        mov     dword ptr [rdi + 16], ecx
        movups  xmm0, xmmword ptr [rip + .L__const.test().values]
        movups  xmmword ptr [rdi], xmm0
        ret
.L__const.test().values:
        .long   0                       # 0x0
        .long   1                       # 0x1
        .long   2                       # 0x2
        .long   3                       # 0x3
        .long   4                       # 0x4
Run Code Online (Sandbox Code Playgroud)

但是对于小型阵列,似乎已经找到了窍门?

std::array<int, 3> test()
{ …
Run Code Online (Sandbox Code Playgroud)

c++ x86-64 abi calling-convention compiler-optimization

33
推荐指数
1
解决办法
1174
查看次数

为什么在x86_64 ABI中选择地址0x400000作为文本段的开头?

文件中.27它说文本段从0x400000开始.为什么选择这个特定的地址?有什么理由吗?相同的地址被选择在GNU ldLinux:

$ ld -verbose | grep -i text-segment
  PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x400000)); . = SEGMENT_START("text-segment", 0x400000) + SIZEOF_HEADERS;
Run Code Online (Sandbox Code Playgroud)

这是令人惊讶的,因为这个地址在32位x86可执行文件中更大:

$ ld -verbose | grep -i text-segment
  PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x08048000)); . = SEGMENT_START("text-segment", 0x08048000) + SIZEOF_HEADERS;
Run Code Online (Sandbox Code Playgroud)

我读了这个问题,讨论为什么为i386选择了0x080xxxxx地址,但它没有解释x86_64的变化.在这个问题上很难找到任何解释.有人有线索吗?

linux memory x86-64 elf abi

32
推荐指数
1
解决办法
2259
查看次数

这是什么意思:指向 void 的指针永远不会等于另一个指针?

我的一个朋友从“理解和使用 C 指针 - Richard Reese,O'Reilly 出版物”中指出了第二个要点,我无法解释其中的一句话。我错过了什么?

空指针

指向 void 的指针是一个通用指针,用于保存对任何数据类型的引用。指向 void 的指针的示例如下所示:

void *pv;
Run Code Online (Sandbox Code Playgroud)

它有两个有趣的特性:

  • 指向 void 的指针将具有与指向 的指针相同的表示形式和内存对齐方式char
  • 指向 void 的指针永远不会等于另一个指针。但是,分配了一个NULL值的两个空指针将是相等的。

这是我的代码,不是书中的代码,所有指针都具有相同的值并且相等。

#include <stdio.h>

int main()
{
  int a = 10; 
  int *p = &a; 
  void *p1 = (void*)&a;
  void *p2 = (void*)&a;

  printf("%p %p\n",p1,p2);
  printf("%p\n",p);
  
  if(p == p1) 
    printf("Equal\n");
  if(p1 == p2) 
    printf("Equal\n");  
}
Run Code Online (Sandbox Code Playgroud)

输出:

 0x7ffe1fbecfec 0x7ffe1fbecfec
 0x7ffe1fbecfec
 Equal
 Equal
Run Code Online (Sandbox Code Playgroud)

c pointers void-pointers

32
推荐指数
4
解决办法
4489
查看次数

汇编语言和机器语言之间有什么关系?

汇编语言和机器语言(对于相同的底层系统)是否真的相同?这两个概念之间有什么不同吗?

architecture assembly operating-system machine-code isa

31
推荐指数
4
解决办法
8万
查看次数

为什么堆栈地址会逐渐减少内存地址?

我在课本中读到堆栈通过减少内存地址而增长; 也就是说,从较高地址到较低地址.这可能是一个糟糕的问题,但我没有把这个概念弄好.你可以解释吗?

stack callstack memory-management virtual-memory

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

为什么Linux(x86)的页面大小为4 KB,如何计算?

x86架构上的Linux内核的默认内存页面大小是4 KB,我想知道这是如何计算的,为什么?

linux x86 kernel cpu-architecture

31
推荐指数
4
解决办法
3万
查看次数

为什么mulss在Haswell上只用了3个周期,与Agner的指令表不同?

我是指令优化的新手.

我对一个简单的函数dotp进行了简单的分析,该函数用于获取两个浮点数组的点积.

C代码如下:

float dotp(               
    const float  x[],   
    const float  y[],     
    const short  n      
)
{
    short i;
    float suma;
    suma = 0.0f;

    for(i=0; i<n; i++) 
    {    
        suma += x[i] * y[i];
    } 
    return suma;
}
Run Code Online (Sandbox Code Playgroud)

我用昂纳雾在网络上提供的测试框架testp.

在这种情况下使用的数组是对齐的:

int n = 2048;
float* z2 = (float*)_mm_malloc(sizeof(float)*n, 64);
char *mem = (char*)_mm_malloc(1<<18,4096);
char *a = mem;
char *b = a+n*sizeof(float);
char *c = b+n*sizeof(float);

float *x = (float*)a;
float *y = (float*)b;
float *z = (float*)c;
Run Code Online (Sandbox Code Playgroud)

然后我调用函数dotp,n = 2048,repeat …

c optimization assembly sse micro-optimization

31
推荐指数
1
解决办法
1471
查看次数

为什么随机设备创建成本昂贵?

C++11 通过该库支持伪随机数生成<random>

我看过多本书籍,其中提到持续构建和销毁std::random_device, std::uniform_int_distribution<>,std::uniform_real_distribution<>对象的成本非常高,并且他们建议在应用程序中保留这些对象的单个副本。

为什么创建/销毁这些对象的成本很高?这里的贵到底是什么意思呢?就执行速度可执行文件大小或其他方面而言,它是否昂贵?

有人可以提供一些解释吗?

c++ random performance c++11

31
推荐指数
2
解决办法
2637
查看次数