1:程式的執行
程式語言----------->編譯器,鏈結器---------->機器語言----------->作業系統載入到記憶體中(檔案系統,記憶體管理)---------->作業系統任務管理與任務排程------------>作業系統輸入輸出------------------->結果
看到程式執行的結構圖,不由得想到c語言編譯過程
c語言過程如下:
.c.**件-——>預處理——>.i檔案——>編譯器——>.s檔案——>彙編器——>.o檔案——>鏈結器對.so.a檔案鏈結——>執行檔案。
以linux gcc為例:(system :ubuntu 14.04, gcc version:4.8.2 )
如程式**mynum.c
#include
#define mynum 123456789
int main(void)
經過gcc -e mynum.c -o mynum.i可得如下內容
# 2 "mynum.c" 2
int main(void)
實現了預處理
在此基礎上進行編譯,gcc -s mynum.i -o mynum.s,得到彙編檔案如下
.file "mynum.c"
.section .rodata
.lc0:
.string "%d\n"
.text
.globl main
.type main, @function
main:
.lfb0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movl $123456789, %esi
movl $.lc0, %edi
movl $0, %eax
call printf
movl $0, %eax
popq %rbp
.cfi_def_cfa 7, 8
ret.cfi_endproc
.lfe0:
.size main, .-main
.ident "gcc: (ubuntu 4.8.2-19ubuntu1) 4.8.2"
.section .note.gnu-stack,"",@progbits
再對其生成目標檔案 gcc -c mynum.s -o mynum.o,此時利用vim開啟或者用cat顯示mynum.o為亂碼
gcc mynum.o -o mynum 即生成執行檔案 此時檔案格式為elf 如果使用交叉編譯,生成的執行檔案格式一般為二進位制檔案
鏈結過程在哪呢?利用命令readelf -d mynum 我們可知我們動態鏈結庫位libc.so.6,其實gcc 預設使用的就是童泰鏈結
2:程式的記憶體布局
***********************************一下內容根據國嵌linux應用程式位址布局
小端模式下
**段 資料段 bss段 堆 棧 堆先上增長,棧向下增長
我們可以通過編寫**檢視資料是如何在記憶體分配的
其中memory.c**如下
#include
#include
int global_init_a = 1;
int global_uinit_a;
static int static_global_init_a = 1;
static int static_global_uinit_a;
const int const_global_a = 1;
int global_init_b = 1;
int global_uinit_b;
static int static_global_init_b = 1;
static int static_global_uinit_b;
const int const_global_b = 1;
int main(void)
在linux下利用 cat /proc/memory程序號/maps檢視**段 資料段 bss段 堆 棧的位址範圍,再由memory各種型別列印的位址對應儲存區域
08048000-08049000 r-xp 00000000 08:01 1052508 /home/liuyanhit/memory//**段
08049000-0804a000 r--p 00000000 08:01 1052508 /home/liuyanhit/memory
0804a000-0804b000 rw-p 00001000 08:01 1052508 /home/liuyanhit/memory//資料段
08a7f000-08aa0000 rw-p 00000000 00:00 0 [heap]//堆
b7519000-b751a000 rw-p 00000000 00:00 0
b751a000-b76c3000 r-xp 00000000 08:01 394206 /lib/i386-linux-gnu/libc-2.19.so
b76c3000-b76c5000 r--p 001a9000 08:01 394206 /lib/i386-linux-gnu/libc-2.19.so
b76c5000-b76c6000 rw-p 001ab000 08:01 394206 /lib/i386-linux-gnu/libc-2.19.so
b76c6000-b76c9000 rw-p 00000000 00:00 0
b76dd000-b76e0000 rw-p 00000000 00:00 0
b76e0000-b76e1000 r-xp 00000000 00:00 0 [vdso]
b76e1000-b7701000 r-xp 00000000 08:01 394182 /lib/i386-linux-gnu/ld-2.19.so
b7701000-b7702000 r--p 0001f000 08:01 394182 /lib/i386-linux-gnu/ld-2.19.so
b7702000-b7703000 rw-p 00020000 08:01 394182 /lib/i386-linux-gnu/ld-2.19.so
bfadc000-bfafd000 rw-p 00000000 00:00 0 [stack]//棧
&global_init_a = 0x804a024, global_init_a = 1//資料段
&global_uinit_a = 0x804a03c, global_uinit_a = 0//資料段
&static_global_init_a = 0x804a028, static_global_init_a = 1//資料段
&static_global_uinit_a = 0x804a034, static_global_uinit_a = 0//資料段
&const_global_a = 0x8048630, const_global_a = 1//**段
&local_init_a = 0xbfafbdf0, local_init_a = 1//棧
&local_uinit_a = 0xbfafbdf4, local_uinit_a = -1217388544//棧
&static_local_init_a = 0x804a02c, static_local_init_a = 1//資料段
&static_local_uinit_a = 0x804a038, static_local_uinit_a = 0//資料段
&const_local_a = 0xbfafbdf8, const_local_a = 1//棧
最後發現
1.**段:**,全域性常量(const)、字串常量
2.資料段:全域性變數(初始化以及未初始化的)、靜態變數(全域性的和區域性的、初始化的以及未初始化的)
3.堆:動態分配的區域
4.棧:區域性變數(初始化以及未初始化的,但不包含靜態變數)、區域性唯讀變數(const)
作業系統基本概念
一.程序的基本狀態 1.初始態 2.就緒態 3.執行態 4.等待態 5.終止 相互轉換關係如下 二.執行緒和程序區別 程序 是作業系統分配資源的最小單位 執行緒 是排程的基本單元,共享所在程序的檔案資料 有自己的棧和程式計數器 一般對於許多相同或相似的任務,傾向於將他們設計為多執行緒模型。因為程序占...
作業系統 基本概念
本文為自己學習 unix環境高階程式設計 而來的學習記錄 我的學習方 是將此書作為工具書來使用,當實際工作中遇到相關的問題針對性地學習知識圓點。基礎概念從嚴格意義上說,可講作業系統定義為一種軟體,它控制計算機硬體資源,提供程式執行環境。系統呼叫 共用函式庫 shell 應用程式 unix系統登陸 a...
作業系統基本概念
1 桌面作業系統 macos linux 2 伺服器作業系統 windows server 3 嵌入式作業系統 linux 4 移動裝置作業系統 iosandroid 基於linux 1965 年之前的時候,電腦並不像現在一樣普遍,它可不是一般人能碰的起的,除非是軍事或者學院的研究機構,而且當時大型...