x86 assembly code
Can anyone tell me what the following code in x86 ASM does? It's only part of a larger file, but it's just this bit that's getting me down.
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开发者_如何学C), %eax
19 movl %eax, -8(%rbp)
Specifically,
- What's initially in %edi on line 13?
- Why is the code referencing -20(%rbp)?
- And what exactly does line 16 do?
- What's the wisdom behind switching behind the 32-bit registers and the 64-bit registers (for instance in the case of line 15)?
The C code I disassembled to get this goes something like the following:
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;
}
What's initially in
%edi
on line 13?
rdi
is the first parameter-passing register for the AMD/Linux 64-bit ABI. edi
is being used in this code since your function takes a 32-bit int
parameter.
Why is the code referencing
-20(%rbp)
?
It's saving the passed-in-parameter to the stack; presumably you are compiling with low or no optimization, so every variable is getting a real memory address. If you turn up the optimizations, you'll probably see these operations disappear.
And what exactly does line 16 do?
Line 16 is an array indexing operation:
movl a(,%rax,4), %eax
The AT&T syntax for memory addressing is a little strange looking. It breaks down as:
segment-override:signed-offset(base,index,scale)
In your case, the array's address is being used as the offset field, you have no base register or segment override, the scale is 4
and the index register being used is rax
. That breaks down to something like along the lines of this C-like pseudocode:
eax = *(int *)((char *)a + (rax * 4))
What's the wisdom behind switching behind the 32-bit registers and the 64-bit registers (for instance in the case of line 15)?
I don't see anything like that on line 15, but the reason it's done is because your function uses a lot of int
- since int
is a 32-bit type, the compiler is using 32-bit registers. Where it doesn't matter or the compiler is using temporary registers, it's choosing the native 64-bit size.
精彩评论