Understanding Assembly

I have a build of the sorting algorithm, and I want to find out exactly how it works.

I am a little confused by some instructions, especially cmp and jle instructions, so I'm looking for help. This assembly sorts an array of three elements.

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

If someone can get through me, it will be very helpful. I got a little confused around operands like 0x8 (% rdi) and cmp and jle commands. Thank you

+3
source share
3 answers
0.00 :        4009f8:       48 8b 07                mov    (%rdi),%rax 

The RDI register contains the address in the memory cell of your array. This line above copies the contents of the RAX register to the first element of your array. Since pointers in x64 are 0x8 bytes, the following two lines:

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 ( [1] [0]). RDX RAX, 400a33. (array [1] > 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];
    }
}
+2

:

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

+4

This helps replace register names with proper names for tracking data flow and add branch labels for the control flow.

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
+4
source

Source: https://habr.com/ru/post/1767291/


All Articles