test.c
int add_a_and_b(int a,int b) {
return a+b;
}
int main() {
int a = 3;
int b = 4;
return add_a_and_b(a, b);
}
编译成汇编文件test.s
gcc -Og -S test.c
hello.s
add_a_and_b:
leal (%rdi,%rsi), %eax //将第1个参数第2个参数相加, 然后放到%eax
ret //函数返回, 返回值一般放在%eax
main:
movl $4, %esi //将4传送到第2个参数
movl $3, %edi //将3传送到第1个参数
call add_a_and_b //调用子程序add_a_and_b
ret //函数返回, 返回值一般放在%eax
hello2.c
#include <stdlib.h>
int add_a_and_b(int *a,int *b) {
return *a+*b;
}
int main() {
int *a = (int *)malloc(sizeof(int));
int *b = (int *)malloc(sizeof(int));
*a = 3;
*b = 4;
int c = add_a_and_b(a,b);
free(a);
free(b);
return c;
}
hello2.s
add_a_and_b:
movl (%rsi), %eax //传送%rsi也就是4到返回值地址
addl (%rdi), %eax //%rdi也就是3加上%eax再把值赋给%eax返回值地址
ret //函数返回
main:
pushq %r12 //入栈
pushq %rbp //入栈
pushq %rbx //入栈
movl $4, %edi //将4传送到第1个参数
call malloc@PLT //调用内存申请程序
movq %rax, %rbp //将malloc返回值传送到%rbp, %rbp存的是内存指针
movl $4, %edi //将4传送到第1个参数
call malloc@PLT //调用内存申请程序
movq %rax, %rbx //将malloc返回值传送到%rbx, %rbx存的是内存指针
movl $3, 0(%rbp) //将3传送到%rbp的内存
movl $4, (%rax) //将4传送到返回值%rax
movq %rax, %rsi //传送%rax到第2个参数
movq %rbp, %rdi //传送%rbp指针到第1个参数
call add_a_and_b //调用子程序
movl %eax, %r12d //传送函数返回值到%r12
movq %rbp, %rdi //传送%rbp指针到第1个参数
call free@PLT //释放第一个参数对应的内存
movq %rbx, %rdi //传送%rbx指针到第1个参数
call free@PLT //释放第一个参数对应的内存
movl %r12d, %eax //传送%r12到返回值
popq %rbx //出栈
popq %rbp //出栈
popq %r12 //出栈
ret //函数返回
编译成二进制文件test.o
gcc -c -o test.o test.c
链接成可执行文件
gcc -o test test.o
objdump反编译二进制文件成汇编代码
objdump -d test.o