1 在没有操作系统时候写assembly的时候,stack的使用是很直接的,申请一块空间,并且在使用pop,push之前将esp赋值为stack空间的最高地址,直接汇编成纯的可执行代码就行。
2 可是当在写有操作系统的assembly代码时候,需要按照操作系统中的assembly格式书写。并将assembly汇编成OS中指定的可执行文件的格式,才能够正确执行,因为在现在的操作系统中,执行这段汇编代码的时候已经是在保护模式中了。
3 在写c代码的时候也是一个道理,在操作系统上运行c程序的时候,不妨以linux的elf文件为例,若为可执行文件的时候,文件中不包括stack空间。stack段是在加载进操作系统时候,系统动态分配的一块空间。只要在程序运行之前将esp的值设定好就可以了。
4 如果不在系统上运行程序,即不调用任何系统的库函数的程序,不妨假设汇编将由c写的elf格式的程序加载进内存,那么需要这段汇编代码负责在内存中空出那么一块空间当做c程序的stack空间,即这段汇编代码负责将esp的值设定好。
小知识:
编译、连接、重定位(不论是链接时重定位还是加载时重定位)对于全局变量、局部变量、函数名的对待方式的不同?
- 对于全局变量、函数名因为可以被程序内任意随机访问到,所以需要在编译时候形成symbol table,并且在重定位时候,将使用这些符号的地方重定位为真实的地址(从cpu的角度来看这些都是logic address),但是就是事实存在的地址了。
- 对于局部变量,全都在编译时变成relative address来访问,就是ip寄存器的地址加上相对偏移量来进行访问,这样局部变量就没有什么重定位的问题了。
小知识:
Heap到底是个啥东西?
The operating system owns and manages the unused memory, and it is collectively known as the heap. The heap is extremely important because it is available for use by applications during execution using the C functions malloc (memory allocate) and free.
下面是运行时候内存情况
OS executable codes
OS global variables
OS stack space
---------------------------
perhaps some free space
--------------------------
App1 executable codes
App1 global variables
App1 stack space
--------------------------------
perhaps some free space
-----------------------------------
App2...Appn
There are free spaces between different segments.