Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

x64 - Why still use 'call'?

In recent windows binaries for example (win 8.1 x64) and programs compiled with VC++ 'call' instruction are still present. Isn't a faster and better way to store the return address into registers, the same way as most of the arguments instead of still using stack?

What I mean:

Function:

func:

; do something

jmp r8

Instance of it:

lea r8, [rip + tmp_1 - tmp_0] ; or rip + 'jmp func' size

tmp_0:

jmp func

tmp_1:

; rest of code
like image 331
AnArrayOfFunctions Avatar asked Dec 14 '22 17:12

AnArrayOfFunctions


1 Answers

Modern x86 micro-architectures have multiple means of making calls via the stack practically free:
1. A dedicated stack engine that keeps the stack pointer synchronised with stack operations during OoO execution.
2. A hardware return stack that keeps return addresses for fast access.

Also, the whole architecture is different than, say, MIPS. MIPS and most other RISCs are load-store, which means they have to store the return address in a register, because otherwise call/return would have to be load/store operations, messing up the orthogonality of the instruction set.

x86 is a register-memory architecture, and is optimized for these accesses, especially with modern micro-architectural features like micro-op fusion, making up for the relatively small number of registers. Finally, this would only ever speed up leaf functions that operate exclusively on registers. That kind of workload can mostly be inlined, reducing the function call cost to zero.
Bottom line: Not worth it.

like image 79
EOF Avatar answered Jan 22 '23 17:01

EOF