I am experiencing a crash, and while investigating I found myself totally blocked by the following code:
0000000000000a00 <_IO_vfprintf>:
a00开发者_运维知识库: 55 push %rbp
a01: 48 89 e5 mov %rsp,%rbp
a04: 41 57 push %r15
a06: 41 56 push %r14
a08: 41 55 push %r13
a0a: 41 54 push %r12
a0c: 53 push %rbx
a0d: 48 81 ec 48 06 00 00 sub $0x648,%rsp
a14: 48 89 95 98 f9 ff ff mov %rdx,0xfffffffffffff998(%rbp)
This is generated by running objdump --disassemble /usr/lib64/libc.a
on a 64-bit Linux x86 system, and then searching through the output. This is AT&T syntax, so destinations are on the right.
Specifically, I don't understand the last instruction. It seems to be writing the value of the rdx
register into memory somewhere on the stack (far, far away), before the function has touched that register. To me, this doesn't make any sense.
I tried reading up on the calling conventions, and my best theory now is that rdx
is used for a parameter, so the code is basically "returning" the parameter value directly. This is not the end of the function, so it's not really returning, of course.
Yes, it's a parameter. The ABI used by Linux assigns up to 6 "INTEGER" (<= 64-bit integer, or pointer) type parameters to registers, in the obvious and easy-to-remember order %rdi
, %rsi
, %rdx
, %rcx
, %r8
, %r9
.
The stack frame is 1648 bytes (sub $0x648,%rsp
claims 1608 bytes, plus 5 64-bit registers have been pushed before that), and 0xfffffffffffff998
is -1640.
So the code is storing the 3rd parameter near the bottom of the stack frame.
(Note: the Windows 64-bit ABI is different to the Linux one.)
精彩评论