汇编 .o目标文件
以编译单元为单位
汇编阶段没有处理的:
1.强弱符号
2.符号表 外部符号处理
3.指令段 虚假地址和虚假偏移
链接阶段处理的:
1.合并段和符号表 强弱符号
2.符号解析
3.分配地址和空间 程序和虚拟地址空间的映射
4.符号的重定位
处理UND区域符号
通过声明找到定义的位置
符号解析
在符号引用的地方找到符号定义的地方
进程
运行
1.建立虚拟地址空间和物理内存的映射(创建内核映射结构体),创建页目录页表
2.加载指令和数据
3.把入口地址放在下一行指令寄存器
下一部分
1.编译链接运行原理
2.函数堆栈调用
寄存器
eax ebx ecx edx 存储数据
ebp 栈底指针寄存器
esp 栈顶指针寄存器
汇编指令
mov dword ptr[a],0Ah 移值指令
a = 10;
lea dword ptr[p],[a]; 移地址指令
int* p = &q
push 0ah; 压栈指令 esp改变
pop eax; 出栈指针 esp改变
eax = pop();
add eax,0a 累加指令
eax += 0a;
sub eax,0a 累减指令
eax -= 0a;
[a] 该内存单元的地址
ptr[a] 该内存单元
#include<stdio.h>
int Sum(int a,int b)//被调用方函数
{
return a + b;
}
void fun()
{
Sum(10,20);
}
int main()//调用方函数
{
int rt = 0;
rt = Sum(10,20);
return 0;
}
问题:函数和函数调用过程中
1.形参开不开辟内存?如果开辟,是调用方开辟,还是被调用方开辟?
实参的传递过程中,形参开辟内存,是由调用方开辟的
2.函数调用完成,怎么回退到调用方?
3.函数调用完成,怎么接着调用方继续指令?
4.函数返回值怎么返回到调用方的?
#include<stdio.h>
int Sum(int left,int right)
{
int tmp = 0;
tmp = left + right
return tmp;
}
int main()
{
int a = 10;
int b = 20;
int rt;
rt = Sum(a,b);
printf("rt:%d\n",rt);
return 0;
}
函数做了哪些事
1.栈帧跳转
调用方跳转到被调用方
2.被调用方预留空间并作初始化(cccc cccc)
call做的事情:
1.压入下一行指令地址
2.jmp 跳转到被调用方
int main()
{
int *p;
*p = 20;//error
return 0;
}
问题:上面的程序错误的原因
因为int *p没有初始化,没有初始化定义指针变量的时候,操作系统是给其预留空间的,预留的空间都是cccc cccc,所以当p里面存放的地址是0xcccc cccc,是内核地址,内核地址只能由操作系统操纵,所以解引用赋值操作错误
{
int *p;
*p = 20;//error
return 0;
}
**问题:上面的程序错误的原因**
因为int *p没有初始化,没有初始化定义指针变量的时候,操作系统是给其预留空间的,预留的空间都是cccc cccc,所以当p里面存放的地址是0xcccc cccc,是内核地址,内核地址只能由操作系统操纵,所以解引用赋值操作错误
