C编译成汇编

cooolr 于 2022-07-22 发布

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