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.
All x86 architectures use a stack as a temporary storage area in RAM that allows the processor to quickly store and retrieve data in memory. The current top of the stack is pointed to by the esp register.
x64 is a generic name for the 64-bit extensions to Intel‟s and AMD‟s 32-bit x86 instruction set architecture (ISA). AMD introduced the first version of x64, initially called x86-64 and later renamed AMD64. Intel named their implementation IA-32e and then EMT64.
In Objective-C, the RDI register is the reference of the calling NSObject , RSI is the Selector, RDX is the first parameter and so on. In Swift, RDI is the first argument, RSI is the second parameter, and so on provided that the Swift method isn't using dynamic dispatch.
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.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With