SA6373 陈彦宏
一、编译文件生成可执行文件
源代码:
#include<stdio.h>
int g(int x)
{
return x+3;
}
int f(int x)
{
return g(x);
}
int main(void)
{
return f(8)+1;
}
保存为example.c
通过指令:
gcc example.c -o example 生成可执行文件
gcc -E -o example.cpp example.c 生成预处理文件
gcc -x cpp-output -S -o example.s example.cpp生成汇编代码
gcc -x assembler -c example.s 生成目标代码
结果如图所示:
二、example.s文件分析
打开example.s:
.file "example.c"
.text
.globl g
.type g, @function
g:
pushl %ebp保存当前基址;
movl %esp, %ebp esp赋值给ebp ;
movl 8(%ebp), %eax相对于ebp+8寻址将内容赋值给eax寄存器;
addl $3, %eax exa寄存器内容+3;
popl %ebp ebp出栈;
ret函数返回
.size g, .-g
.globl f
.type f, @function
f:
pushl %ebp 保存当前基址
movl %esp, %ebp esp赋值给ebp
subl $4, %esp esp下移4单位
movl 8(%ebp), %eax 相对于ebp+8寻址将内容赋值给eax寄存器
movl %eax, (%esp) 将eax内容存入esp所指向的地址
call g 调用函数g
leave ebp赋给esp,pop先前栈内的上级函数栈的基地址给ebp,恢复原栈基址
ret 函数返回
.size f, .-f
.globl main
.type main, @function
main:
pushl %ebp ebp压栈 esp指针下移4单位
movl %esp, %ebp 将esp赋值给ebp
subl $4, %esp esp下移4个单位
movl $8, (%esp) 立即数8 存入esp所指向的空间
call f 调用函数f
addl $1, %eax 1与eax寄存器所保存的值相加
leave ebp赋给esp,pop先前栈内的上级函数栈的基地址给ebp,恢复原栈基址
ret 函数返回
.size main, .-main
.ident "GCC: (Ubuntu/Linaro 4.5.2-8ubuntu4) 4.5.2"
.section .note.GNU-stack,"",@progbits
我们从main函数开始对该汇编语言进行分析:
三、单任务、多任务计算机工作原理
根据实验我们可以分析出来单任务计算机的工作原理是一个取出指令、分析指令、执行指令的一个过程,根据指令进行入栈出栈的操作来实现,如上述程序分析所示,当调用其他函数时,会保存目前的栈基址,来起到一个保存现场的作用,通过leave恢复该栈基址,就像一个控制流,按程序编排的顺序,一步一步地取出指令、完成指令,从main函数开始,最后从main结束。
而多任务计算机的工作原理可以理解为,计算机快速的在多个任务间跳转执行,其速度很快以致人们无法分别当前任务是否暂停。通过CPU时间片轮转,分给每个任务特定的时间,当某个任务的执行时间结束后,保存现场,然后跳转至其他任务恢复之前该任务保存的现场,继续执行,然后时间到后同样保存现场,这样循环来实现多任务处理。