了解大会

时间:2010-09-30 02:11:50

标签: sorting assembly

我有一些排序算法的组装,我想知道它的确切功能。

我对一些说明有点困惑,特别是cmp和jle指令,所以我正在寻求帮助。该程序集对三个元素的数组进行排序。

0.00 :        4009f8:       48 8b 07                mov    (%rdi),%rax
0.00 :        4009fb:       48 8b 57 08             mov    0x8(%rdi),%rdx
0.00 :        4009ff:       48 8b 4f 10             mov    0x10(%rdi),%rcx
0.00 :        400a03:       48 39 d0                cmp    %rdx,%rax
0.00 :        400a06:       7e 2b                   jle    400a33 <b+0x3b>
0.00 :        400a08:       48 39 c8                cmp    %rcx,%rax
0.00 :        400a0b:       7e 1a                   jle    400a27 <b+0x2f>
0.00 :        400a0d:       48 39 ca                cmp    %rcx,%rdx
0.00 :        400a10:       7e 0c                   jle    400a1e <b+0x26>
0.00 :        400a12:       48 89 0f                mov    %rcx,(%rdi)
0.00 :        400a15:       48 89 57 08             mov    %rdx,0x8(%rdi)
0.00 :        400a19:       48 89 47 10             mov    %rax,0x10(%rdi)
0.00 :        400a1d:       c3                      retq
0.00 :        400a1e:       48 89 17                mov    %rdx,(%rdi)
0.00 :        400a21:       48 89 4f 08             mov    %rcx,0x8(%rdi)
0.00 :        400a25:       eb f2                   jmp    400a19 <b+0x21>
0.00 :        400a27:       48 89 17                mov    %rdx,(%rdi)
0.00 :        400a2a:       48 89 47 08             mov    %rax,0x8(%rdi)
0.00 :        400a2e:       48 89 4f 10             mov    %rcx,0x10(%rdi)
0.00 :        400a32:       c3                      retq
0.00 :        400a33:       48 39 ca                cmp    %rcx,%rdx
0.00 :        400a36:       7e 1d                   jle    400a55 <b+0x5d>
0.00 :        400a38:       48 39 c8                cmp    %rcx,%rax
0.00 :        400a3b:       7e 0c                   jle    400a49 <b+0x51>
0.00 :        400a3d:       48 89 0f                mov    %rcx,(%rdi)
0.00 :        400a40:       48 89 47 08             mov    %rax,0x8(%rdi)
0.00 :        400a44:       48 89 57 10             mov    %rdx,0x10(%rdi)
0.00 :        400a48:       c3                      retq
0.00 :        400a49:       48 89 07                mov    %rax,(%rdi)
0.00 :        400a4c:       48 89 4f 08             mov    %rcx,0x8(%rdi)
0.00 :        400a50:       48 89 57 10             mov    %rdx,0x10(%rdi)
0.00 :        400a54:       c3                      retq
0.00 :        400a55:       48 89 07                mov    %rax,(%rdi)
0.00 :        400a58:       48 89 57 08             mov    %rdx,0x8(%rdi)
0.00 :        400a5c:       48 89 4f 10             mov    %rcx,0x10(%rdi)
0.00 :        400a60:       c3                      retq
0.00 :        400a61:       90                      nop

如果有人可以引导我完成它,那将非常有帮助。我有点混淆操作数,如0x8(%rdi)和cmp和jle指令。谢谢。

3 个答案:

答案 0 :(得分:4)

以下是说明的含义:

mov : move
cmp : compare
jle : jump if less or equal (branch)
ret : return from procedure
nop : no-op

%r**是寄存器。它们通常是%e**(例如:%eax%edx,...),但这些是64位寄存器。

对于整个事情的反编译,这将需要更多的工作。

请参阅:http://www.x86-64.org/documentation/assembly

答案 1 :(得分:4)

有助于用适当的名称替换寄存器名称以跟踪数据流,并为控制流添加分支标签。

0.00 :        4009f8:       48 8b 07                mov    (%argptr),%var1
0.00 :        4009fb:       48 8b 57 08             mov    0x8(%argptr),%var2
0.00 :        4009ff:       48 8b 4f 10             mov    0x10(%argptr),%var3
0.00 :        400a03:       48 39 d0                cmp    %var2,%var1
0.00 :        400a06:       7e 2b                   jle    @v2le1
0.00 :        400a08:       48 39 c8                cmp    %var3,%var1
0.00 :        400a0b:       7e 1a                   jle    @v3le1
0.00 :        400a0d:       48 39 ca                cmp    %var3,%var2
0.00 :        400a10:       7e 0c                   jle    @v3le2

   # Now we know that 2 > 1 and 3 > 1 and 3 > 2. Write them to memory in order.

      etc

答案 2 :(得分:2)

0.00 :        4009f8:       48 8b 07                mov    (%rdi),%rax 

寄存器RDI包含阵列内存中某个位置的地址。上面的这一行将RAX寄存器的内容复制到数组的第一个元素中。由于x64中的指针是0x8字节,因此以下两行:

0.00 :        4009fb:       48 8b 57 08             mov    0x8(%rdi),%rdx 
0.00 :        4009ff:       48 8b 4f 10             mov    0x10(%rdi),%rcx 

将RDX和RCX寄存器的内容分别复制到数组的第二个和第三个元素中。现在我们需要开始比较这些值以查看我们需要交换的位置。

0.00 :        400a03:       48 39 d0                cmp    %rdx,%rax 
0.00 :        400a06:       7e 2b                   jle    400a33 <b+0x3b> 

cmp将比较RDX的值与RAX的值(对阵列[0]基本上是数组[1])。如果RDX小于或等于RAX,那么这将直接将程序执行跳转到行400a33。您可以将其视为(array [1]&gt; array [0])。所以它继续,比较价值。

似乎代码正在尝试按降序排序。非常粗略地说,C代码可能看起来像这样:

array[0] = rax;
array[1] = rdx;
array[2] = rcx;

if (rdx > rax)
{
    if (rcx > rax)
    {
        if (rcx > rdx)
        {
            rcx = array[0];
            rdx = array[1];
LABEL:
            rax = array[2];
        }
        else
        {
            rdx = array[0];
            rcx = array[1];
            GOTO LABEL;
        }
    }
    else
    {
        rdx = array[0];
        rax = array[1];
        rcx = array[2];

    }
}
else
{
    if (rcx > rdx)
    {
        if (rcx > rax)
        {
            rcx = array[0];
            rax = array[1];
            rdx = array[2];
        }
        else
        {
            rax = array[0];
            rdx = array[1];
            rcx = array[2];
        }
    }
    else
    {
        rax = array[0];
        rdx = array[1];
        rcx = array[2];
    }
}