首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >x86汇编代码

x86汇编代码
EN

Stack Overflow用户
提问于 2011-06-22 17:12:33
回答 1查看 647关注 0票数 0

有人能告诉我x86 ASM中的以下代码是干什么的吗?这只是一个更大的文件的一部分,但正是这一点让我失望了。

代码语言:javascript
复制
find_max:
  6 .LFB0:
  7         .cfi_startproc
  8         pushq   %rbp
  9         .cfi_def_cfa_offset 16
 10         movq    %rsp, %rbp
 11         .cfi_offset 6, -16
 12         .cfi_def_cfa_register 6
 13         movl    %edi, -20(%rbp)
 14         movl    -20(%rbp), %eax
 15         cltq
 16         movl    a(,%rax,4), %eax
 17         movl    %eax, -4(%rbp)
 18         movl    -20(%rbp), %eax
 19         movl    %eax, -8(%rbp)

具体来说,

  • ,最初在第13行的%edi中有什么?
  • ,为什么代码引用-20(%rbp)?
  • ,以及第16行到底要做什么?
  • ,在32位寄存器和64位寄存器后面切换(例如,在第15行)后面有什么智慧?

< code >f 210

我分解的C代码如下所示:

代码语言:javascript
复制
extern int a[];

int find_max(int n)
{
    int max = a[n];
    int pos = n;
    int x;

    while (n > 0)
    {
        n--;
        x = a[n];

        if (x > max)
        {
            max = x;
            pos = n;
        }
    } 
    return pos;
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-06-22 17:22:45

在第13行的%edi中,

最初是什么?

rdi是AMD/Linux64位ABI的第一个参数传递寄存器.在这段代码中使用edi,因为您的函数采用32位int参数。

为什么引用-20(%rbp)?的代码

它将传递的参数保存到堆栈中;假设您正在进行低优化或无优化的编译,因此每个变量都获得了一个真正的内存地址。如果您打开优化,您可能会看到这些操作消失。

和第16行到底是做什么的?

第16行是数组索引操作:

代码语言:javascript
复制
movl    a(,%rax,4), %eax

用于内存寻址的AT&T语法看起来有点奇怪。它的分类如下:

段-覆盖:符号偏移量(基、索引、缩放)

在您的例子中,数组的地址被用作偏移字段,您没有基本寄存器或段覆盖,缩放是4,使用的索引寄存器是rax。它可以分解成类似于C类伪代码的代码:

代码语言:javascript
复制
eax = *(int *)((char *)a + (rax * 4))

,在32位寄存器和64位寄存器后面切换(例如,在第15行)背后的智慧是什么?

我在第15行没有看到类似的情况,但是之所以这样做是因为您的函数使用了大量的int,因为int是32位类型,编译器使用32位寄存器。在不重要的地方,或者编译器正在使用临时寄存器时,它选择的是本机64位大小。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6443812

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档