加载程序是操作系统的程序,它将可执行文件从磁盘加载到主内存(RAM)中以供执行。它将内存空间分配给主内存中的可执行模块,然后将控制权转移到程序的开始指令。
例子:
akash @aix(/ u / akash) #cat./ ak1.cpp
#include
int main()
{
printf("Testing of Loader !");
return 0;
}
通过xlC编译器进行编译:
akash @aix(/ u / akash) #xlC – o ak1.out./ ak1.cpp akash @aix(/ u / akash) #ls – lrt ak1 * -rw – rw – r– 1 akash dev 74 Nov 12 06 : 10 ak1.cpp
– rwxrwxr – x 1 akash dev 8562 Nov 12 06 : 34 ak1.out akash @aix(/ u / akash) #
运行可执行文件时真正发生的情况:也可以使用strace命令。
akash@aix(/u/akash)# truss ./ak1.out
execve(“./ak1.out”, 0x2FF20A00, 0x200138A8) argc: 1
read_sysconfig(0xF06F8278, 0x00000010, 0xFFFFFFF9, 0x10000000, 0x200007BC, 0x000000C0, 0x06010000, 0xF076A0F0) = 0x00000000
sbrk(0x00000000) = 0x20000998
vmgetinfo(0x2FF20350, 7, 16) = 0
sbrk(0x00000000) = 0x20000998
sbrk(0x00000008) = 0x20000998
__libc_sbrk(0x00000000) = 0x200009A0
loadquery(2, 0x200009C8, 0x00001000) = 0
__loadx(0x0A040000, 0xF06F599C, 0x00000000, 0xF05BE208, 0x20001D20) = 0xF05BFD64
loadbind(0, 0xF0760BBC, 0xF06D0E54) = 0
kfcntl(0, F_GETFL, 0x00000000) = 67110914
kfcntl(1, F_GETFL, 0x00000000) = 67110914
kfcntl(2, F_GETFL, 0x00000000) = 67110914
kfcntl(2, F_GETFL, 0x00000000) = 67110914
kioctl(1, 22528, 0x00000000, 0x00000000) = 0
Testing of Loader !kwrite(1, ” T e s t i n g o f L”.., 19) = 19
kfcntl(1, F_GETFL, 0x00000070) = 67110914
kfcntl(2, F_GETFL, 0x2FF22FFC) = 67110914
_exit(0)
显示的第一个调用是’ execve() ‘,它实际上是加载程序。该加载器创建的过程涉及:
- 读取文件并为该进程创建地址空间。
- 创建指令,数据和程序堆栈的页表条目,并初始化寄存器集。
- 然后,执行通常会导致页面错误的程序第一条指令的跳转指令,并将指令的第一页存储到内存中。
以下两点与加载程序无关,仅用于提供更多信息:
- 我们得到的另一件事是带有参数值的kwrite调用,该参数值已传递给程序中的printf函数。 kwrite是系统调用,实际上是通过传递给它的值从printf函数调用的,并且该函数负责将传递给它的值显示到控制台。
- 我们在最后一条指令中也得到了_exit(0)调用,这是_exit系统调用,参数状态为0,表示以成功的信号返回操作系统。这个_exit是从return(0)语句调用的。