为了理解下面发生了什么,我正在制作小型C程序,然后将其反转,并尝试理解其objdump输出.
C程序是:
#include <stdio.h>
int function(int a, int b, int c) {
printf("%d, %d, %d\n", a,b,c);
}
int main() {
int a;
int *ptr;
asm("nop");
function(1,2,3);
}
Run Code Online (Sandbox Code Playgroud)
函数的objdump输出给出了以下内容.
080483a4 <function>:
80483a4: 55 push ebp
80483a5: 89 e5 mov ebp,esp
80483a7: 83 ec 08 sub esp,0x8
80483aa: ff 75 10 push DWORD PTR [ebp+16]
80483ad: ff 75 0c push DWORD PTR [ebp+12]
80483b0: ff 75 08 push DWORD PTR [ebp+8]
80483b3: 68 04 85 04 08 push 0x8048504
80483b8: e8 fb fe ff ff call 80482b8 <printf@plt>
80483bd: 83 c4 10 add esp,0x10
80483c0: c9 leave
Run Code Online (Sandbox Code Playgroud)
请注意,在调用printf之前,三个带有偏移量8,16,12的DWORD(它们必须是function相反顺序的参数)被压入堆栈.之后会推送一个十六进制地址,它必须是格式字符串的地址.
My doubt is
好吧,有些机器有一个堆栈指针,就像任何其他寄存器一样,所以推送东西的方式是,减少后跟商店.
但是有些机器,比如x86 32/64,有一个执行宏操作的push指令:递减指针并进行存储.
宏观操作,顺便说一句,有一个有趣的历史.有时,某些机器上的某些示例比使用简单指令执行基本操作要慢.
我怀疑今天是否经常出现这种情况.现代x86非常精致.CPU会将您的操作码本身分解为微操作,然后将其存储在缓存中.微操作具有特定的流水线和时隙要求,最终结果是x86内部有一个RISC cpu,整个过程非常快,具有良好的架构层代码密度.