嵌入式软件工程师&&太极拳
全部博文(548)
分类: LINUX
2011-02-20 19:53:48
链接器的主要作用有2个: 1. 修改目标文件中的信息,对地址做重定位; 2. 把多个目标文件合并成一个可执行文件。 x86汇编基础: #xxx /*注释一行*/ .section /*指示把代码划分成若干个section,程序被os加载时,每个段加载到不同的地址,os对不同页面设置不同r/w/e权限*/ 函数调用和返回过程的规则: 1. 参数通过压栈来传递,并且是从右向左依次压栈; 2. ebp总是指向栈帧的栈底; 3. 返回值通过eax寄存器传递。 这些规则并不是体系结构所强加的,ebp寄存器并不是必须这么用 ,函数的参数和返回值也不是必须这么传。 只是操作系统和编译器选择了以这样的方式实现C代码中的函数 调用,这称为Calling Convention,除了Calling Convention以外 ,操作系统还需要规定许多C代码和二进制指令之间的接口规范, 统称为ABI(Application Binary interface)。 x86指令: call: 1. 将call的下一条指令的地址压栈,同时把esp值减4; 2. 修改程序计数器eip,跳转到函数的开头执行。 leave: 是push %ebp和mov %esp, %ebp的逆操作。 1. 把ebp的值赋给esp; 2. esp所指向的栈顶保存着ebp,把这个值恢复给ebp,同 时esp增加4。 ret: 是call指令的逆操作。 1. esp所指向的栈顶保存着返回地址,把这个值恢复给 eip,同时esp增加4; 2. 修改程序计数器eip,跳回到返回地址继续执行。 x86的寄存器: eip: 程序计数器 esp: 栈指针(对于每个函数来说,总是指向栈顶,保持不变) ebp: 指向栈底(对于每个函数来说,随压栈和出栈随时变化) eax: 保存函数返回时的临时变量。