1、8086汇编参考链接:
1.1、函数调用原理–参数篇
1.2、函数调用原理–局部变量篇
1.3、函数调用原理–完善篇(栈帧)
2、简单C++代码
1 2 3 4 5 6 7 8 9 10 11 12 | #include <iostream> #include <cmath> using namespace std; int sum(int a, int b){ return a + b; } int main(){ sum(1, 2); return 0; } |
3、XCode中编译以上代码得到的汇编代码
3.1、main函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | cplus`main: 0x100000f80 <+0>: pushq %rbp;保护bp 0x100000f81 <+1>: movq %rsp, %rbp;保护sp 0x100000f84 <+4>: subq $0x10, %rsp;在栈中预留10H个空间给局部变量 0x100000f88 <+8>: movl $0x1, %edi;加载第一个参数到di 0x100000f8d <+13>: movl $0x2, %esi;加载第二个参数到si 0x100000f92 <+18>: movl $0x0, -0x4(%rbp); 0x100000f99 <+25>: callq 0x100000f60;调用sum()函数 0x100000f9e <+30>: xorl %esi, %esi 0x100000fa0 <+32>: movl %eax, -0x8(%rbp);取出结果 0x100000fa3 <+35>: movl %esi, %eax 0x100000fa5 <+37>: addq $0x10, %rsp;恢复sp 0x100000fa9 <+41>: popq %rbp;恢复bp 0x100000faa <+42>: retq ;返回 |
3.2、sum函数
1 2 3 4 5 6 7 8 9 10 | cplus`sum: 0x100000f60 <+0>: pushq %rbp;保护bp 0x100000f61 <+1>: movq %rsp, %rbp;保护sp 0x100000f64 <+4>: movl %edi, -0x4(%rbp);加载第一个参数到局部变量区域 0x100000f67 <+7>: movl %esi, -0x8(%rbp);加载第二个参数到局部变量区域 0x100000f6a <+10>: movl -0x4(%rbp), %esi;将第一个参数加载到si 0x100000f6d <+13>: addl -0x8(%rbp), %esi;累加第二个参数的值 0x100000f70 <+16>: movl %esi, %eax;结果存储到ax中 0x100000f72 <+18>: popq %rbp;恢复bp 0x100000f73 <+19>: retq;返回 |
AT&T函数参数传递直接使用寄存器,类似默认函数约定调用方式为__fastcall,AT&T通用寄存器有16个