[20170226]由GCC汇编理解程序调用

<课堂笔记>

预备知识:

1.堆栈/栈: 如何被CPU维护,函数调用需要用到堆栈
2.寄存器:内存中的数据需要读入寄存器才能被CPU计算,
常用的寄存器EAX/EBX/ECX/EDX为通用寄存器
EBP:当前栈帧的开始处(若干函数调用形成一个堆栈,其中一个元素为一个栈帧)
ESP:指向函数栈的栈顶
EBP/ESP寄存器只有一个,函数调用需要保存现场就要把EBP入栈

3.GCC 汇编指令(ATT语法)



4.从硬盘到内存(进程的虚拟内存空间)


5.PUSH EBP 导致  ESP自动减4,栈生长,POP EBP导致 ESP+4,栈收缩
6.无法判断内存存放的是值还是地址,只有程序知道

高级语言实现及其汇编代码分析

C语言实现:
int demo(){
    int x = 10;
    int y = 20;
    int sum = add(&x,  &y);
    printf(“the sum is %d\n”,sum);
    return sum;
}
int add(int *xp, int *yp){
    int x = *xp;
    int y = *yp;
    return x+y;
}

GCC 汇编

调用者demo

1 pushl %ebp 		//把ebp的值放到栈顶,同时esp-4,栈生长
2 movl %esp %ebp	//
3 subl %24 esp		//把esp值减去24个字节,相当于为函数分配了内存空间。ESP=776
4 movl $10 -4(%ebp) 	//$10表示立即数,把数字10存放到ebp值-4的内存地址中
5 movl $20 -8(%ebp) 	//把数字20存放到ebp值-8的内存地址中
			//思考:变量名存放哪里? 在汇编中不需要变量名,所有操作都是针对地址和寄存器
6 leal -8(%ebp) %eax	//把ebp存放的地址-8 放到 Eax寄存器,实际上就是指向
7 movl %eax 4(%esp) 	//把792 放到esp+4的内存地址
8 leal -4(%ebp) %eax
9 movl %eax (%esp)	//6-9行实际上实现了对x,y的指针
10 call add		//进入对add函数的调用
11 打印结果(略)--地址是100



被调用者函数add

1 push %ebp
2 movl %esp %ebp
3 pushl %ebx			//保存现有的值,该存储器将要使用,intel约定,eax,ecx,edx寄存器调用者保存,ebx由被调用者保存
4 movl 8(%ebp) %edx		//思考:到此edx的值是多少? ebp=768+8=776,addr776 value=796
5 movl 12(%ebp) %ecx		//思考:到此ecx的值是多少? ebp=768+12=780,addr780 value=782
6 movl (%edx) %ebx		//把ebx中地址的值放入ebx,根据地址从内存中取值
7 movl (%ecx) %eax		//把ecx中地址的值放入eax,根据地址从内存中取值
8 add %ebx %eax 
9 popl %ebx
10 popl %ebp
11 ret


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值