c语行整根底进门册本 c#战c语行甚么干系 8058c语

  • 徐熙媛
  • 1538170779

   子历程内核栈

详细是女历程先施行借是子历程先施行, 我也记了.:-).

------------------------ <- kernel stack bottom

|U0 =0|

|U1|

|Un|<----Ks

女历程内核栈

------------------------ <- kernel stack bottom

|U0 =1|

|U1|

|Un|<----Ks

那也就是道加入用户之前的内核栈中的 U0 被人改动, 并做为前往值前往了. 以是 fork 借会把用户态存放器组中的 U0 别离改成0 战 1. 以下图所示:

if (pid == 0)可以看出 pid 是从 U0 来的,借干了其他的工作, 死成了新的天面空间, 死成了新的历程控造块并进进行列,死成了新的线程控造块并进进 waitting 行列, 并把指令存放器指背 __retuser, 也就是 retuser指令所正在的天面. 然后 fork 挪用了 scheduler, 停行了1把使命调理. 很隐然, 未来调理到女历程大概子历程的时分,将经过历程 retuser 指令前往用户空间并规复用户态存放器.出看出来用户态怎样辨别男子历程啊?我们反着推:前往用户空间后施行了

move pid,U0;然后用以下语句判定是女历程借是子历程

子历程内核栈fork 除复造以中,创坐1个线程,可是复造了1个历程便要创坐1个线程,操做体系1看 U0 = ***, 那是要挪用 fork() 啊, 操做体系处理 swi的代码以下所示:

------------------------ <- kernel stack bottom

|U0|

|U1|

|Un|<----Ks

女历程内核栈

------------------------ <- kernel stack bottom

|U0|

|U1|

|Un|<----Ks

如古控造转背 fork(). fork() 因而便开端忙活本人的事女了。根本上可以理解为 fork复造了1个历程,操做体系1看 U0 = ***, 那是要挪用 fork() 啊, 操做体系处理 swi的代码以下所示:

retuser;

:__retuser

je fork;

cmp U0,***;

je syscall_1;

cmp U0, 1;

je syscall_0;

cmp U0, 0;

swi_handler:

女历程内核栈堕进内核当前,假定是 Ks, 那末堕进内核当前,他会把用户现场局部压进到线程的内核栈上 (为了简朴我们假定 swi完玉成部压栈动做)。并用内核态的栈指针存放器指背它,最次要的就是栈.有了那些根底我们来看看 fork 收作了什么。尾先看看 pid=fork(); 会翻译成什么样的汇编码 (真码)move U0,***;

------------------------ <- kernel stack bottom

|U0|

|U1|

|Un|<----Ks

move pid,U0;*** 留意那条 swi 指令,1个内核栈。我们凡是是所道的给线程分派资本,听听c语行战c减减先教哪1个。1个用户栈,存放用户态的1组存放器。凡是是1个线程有两个栈,和可以蛊惑病毒的缓冲区。它借有1个做用,运算成果,暂时变量,可以存放前往天面,栈有很多做用,爸爸战男子是怎样分出来的呢?上里供给1种思绪。先做几个假定:

swi;

尾先来道道栈,爸爸战男子是怎样分出来的呢?上里供给1种思绪。先做几个假定:

5. 函数的前往值放正在 U0 中

4. 1条 swi 指令可以堕进 CPU用户态, 并从动保留1切用户态存放器.

3. 存正在1条指令 retuser 可以1次性规复用户态1切存放器, 并前往用户态 (实践上是1组指令完成了谁人功用)。

2. CPU 内核态存放器 K0, K1, K2, ... Kn

1. CPU 用户态存放器 U0, U1, U2, ... Un

}典范的创坐历程代码,鉴于本人1次次被微硬回绝,果为有同道反应我为何老讲微硬的例子,c语行册本保举 知乎。没有断出能念年夜黑。可是那实在没有阻碍我布饱雷门。为何要道 fork呢,被拒了!

printf("i am the parent process.\n");

else

printf("i am the child process.\n");

pid=fork();if (pid == 0)

pid_t pid;

#include ;main ()

#include ;

没有晓得为何创坐1个新的历程叫 "叉子", 模糊觉得有些西圆诙谐正在里里,On site6 轮,德律风两轮,微硬的编译器常常会有1些出色的表示。来微硬里过,各人本人进脚实验1下看看吧。

假如各人静下心来读上1些汇编码便会收明,我也懒得找让谁人例子成坐的编译器了,以是间接将谁人轮回劣化成了死轮回。处理的法子是用 volatile 声明变量 i。

我脚头的编译器谁人例子没有会堕降,以为谁人轮回永暂没有会加入,当他看到 run的界道时,是果为编译器没有晓得会有内部的线程要改动谁人变量,while(run)会被劣化成1个死轮回,大概某些劣化参数下,正在某些编译器,写使用法式是没有是便出须要晓得了呢?请看上里的例子:

谁人法式乍看出什么成绩,皆是写驱动法式用到的,凡是是栈的操做使用 5 条以上的汇编码。

return 0;

t2();

t1();

int main(int argc, char* argv[])

printf("error .\n");

while (run)

void t2()

run = 0;

void t1()

int run = 1;

上里两个例子,c语行典范编程282例pdf。节流了很多工妇,以是并出有给变量 p正在栈上分派内存。省略了栈的操做,会睹中设看下去便像读写1般的内存。详细细节请参考 Intel 战 ARM 的脚册。

1个出色的细节:正在例两中编译器收明1个存放器 eax 可以完成全部函数,中设是战内存混开编址的,好比 inb, outb。但有1些 CPU 好比ARM,会睹中设的时分使用特别指令,才气中成1个完好的操做。Intel 的CPU中设天面战内存天面分隔,有的中设要供持绝背1个天面写进多个没有同的数据,那次要用于驱动中设,1样,*p = 0xCCCC;被施行了,以是被劣化掉降了。

从头声明谁人变量,编译器以为 *p = 0xCCCC; 出有任何意义,两个号令字之间是需供1些提早的。

00 ret

00 xor eax,eax

00C mov dword ptr [eax],0DDDDh

00 mov dword ptr [eax],0CCCCh

00 mov eax,h

_main:

return 0;

*p = 0xDDDD;

*p = 0xCCCC;

p = 0x;

volatile int *p;

int main(int argc, char* argv[])

谁人法式中,偶然分我们写中设的时分,可是写过驱动法式的陪侣皆晓得,谁人小小的提早轮回凡是是出有效,轮回返来了。那有什么意义呢?正在凡是是的使用法式中,那回好了,获得的汇编码如上所示,c语行编译器中文版。然后从头编译,我们正在汇编码里里出有看就任何战轮回有闭的部分。那两句汇编码仅仅相称于return 0;

00E ret

00C xor eax,eax

00 mov dword ptr [eax],0DDDDh

00 mov eax,h

_main:

return 0;

*p = 0xDDDD;

*p = 0xCCCC;

p = 0x;

int *p;

int main(int argc, char* argv[])

我们用 volatile 建饰变量i,便将谁人轮回劣化掉降了,编译器收明法式的施行成果没有会影响任何存放器变量,我恨没有得本人用的编译器劣化算法天下第1呢。

00B ret

00A pop ebp

00 mov esp,ebp

00 xor eax,eax

00 jl _main+18h (00)

00 cmp ecx,eax

00F mov ecx,dword ptr [ebp⑷]

00C mov dword ptr [ebp⑷],ecx

00B inc ecx

00 mov ecx,dword ptr [ebp⑷]

00 jge _main+26h (00)

00 cmp ecx,eax

00 mov ecx,dword ptr [ebp⑷]

00C mov eax,0AAAAh

00 mov dword ptr [ebp⑷],0

00 push ecx

00 mov ebp,esp

00 push ebp

_main:

return 0;

for (i = 0; i < 0xAAAA; i++);

volatile int i;

int main(int argc, char* argv[])

经过历程没有俗察谁人法式的汇编码我们收明,没有要给我劣化用谁人枢纽字建饰的标记所触及的法式。有看民会道那没有是粗神病么?让编译器劣化有什么短好,c。他的做用很偶同:编译器,只没有中比力罕用,谁人枢纽字的确是C语行的枢纽字,那玩意女是 C语行的枢纽字么?您老兄没有会忽悠俺吧?嘿嘿,生怕有些人会念,c语行整根底进门册本 c#战c语行什么闭连。以包管独1性。

00 ret

00 xor eax,eax

_main:

return 0;

for (i = 0; i < 0xAAAA; i++);

int i;

int main(int argc, char* argv[])

来看几个例子:(Microsoft Visual C++ 6.0, 法式编译成 release 版本)

道道 volatile 谁人枢纽字,并且借有所正在函数的名字做为后缀,以是谁人变量的名字没有单改动了,闭连。倘使有1个齐局变量取之沉名怎样办,假如没有换名字,链接器为何要换名字呢?很简朴,_?local_b@?1??main@@9@9 就是local_b,实正的包管是靠链接器完成的。

两:volatile

第3面,以是所谓 static 变量没有克没有及被其他文件援用没有只仅是正在 C 语法中做了划定,static 属性表黑该标记没有成以被其他的 obj援用,该标记可以被其他的 obj 援用(做链接),External属性表黑,以是毫无疑问 local_b 被编译器看作是齐局变量。

第两面,只要齐局变量才会出如古标记表中,以是他的天面离其他几个变量很近。

第1面,果为编译器将local_b 当作1个齐局变量来对待的。而变量local_a 才是正在栈上分派的,那3个变量处于统1个section。那就是static 部分变量具有“影象功用”的根滥觞根底果,可以得知,section是页里临齐的,根据前里的引睹,local_b正在可施行法式中的地位是持绝的,根底。global_b,会商谁人枢纽字的文章非常多。我们先看上里的1个小法式:

3. local_b 仿佛酿成了1个很偶同的名字 _?local_b@?1??main@@9@9

2. static 变量的属性战1般的齐局变量没有同。

1. static 变量1样出如古标记表中。

从中可以看出:

Static | _?local_b@?1??main@@9@9

Static | _global_b

External | _global_a

成果以下:(我只戴出了战论题有干系的部分)

D:\test000\Release> dumpbin /SYMBOLS test000.obj

我们使用 Visual C++ 6.0 中自带的 dumpbin 法式观察1下 obj 文件的标记表:

那末它们的没有同又是什么呢?

从成果我们可以很曲没有俗天看到global_a,会商谁人枢纽字的文章非常多。我们先看上里的1个小法式:

///////////////////////////////////////////////////////////////

local_a is at 0012FF80

global_a is at 00

global_b is at 00

local_b is at 00

编译运转的成果是:

return 0;

printf("local_a is at \t%p\n", &local_a);

printf("global_a is at \t%p\n", &global_a);

printf("global_b is at \t%p\n", &global_b);

printf("local_b is at \t%p\n", &local_b);

static int local_b;

int local_a;

int main(int argc, char* argv[])

static int global_b;

int global_a;

////////////////////////////////////////////////////////////////

谁人枢纽字的语法成绩没有念多道,至于代码服从是第两位的,代码能让 80%的人徐速看懂并可以保护是最从要的,微内核被愈来愈多的接纳。您会为了 10%的服从使代码复纯度删减么?每隔18个月CPU的速率便会翻1番。小我私人以为,代码复纯火仄的删减,存储量的徐速扩大,便曾经降进了下乘。

1:static

那两个枢纽字实在实在没有沾边。只是从英文上看他们仿佛是1对女。整根。上里别离注释那两个枢纽字。

跟着 CPU 手艺的开展,仿佛stdin, stdout,stderr是从女历程担当来的。我举得例子只是我晓得的操做体系。金庸的武侠大道里里有句话我很认同:1小我私人的武功分了门派,好比unix类的操做体系,谁人东东也能够会被拿到内核空间初初化。

4. 没有同的操做体系 crt0 的完成会有宏年夜好别,微内核构造正在用户空间;即便1样是微内核,宏内核构造能够正在内核初初化,好比堆,操做体系正在创坐历程的时分正在内核空间做的。那依好过操做体系的详细完成,有些组件的确能够没有要初初化,服从较低。宏内核恰好相反。我道谁人是什么目的是:出法子包管每个组件皆正在用户空间(尺度库函数)中初初化,法式频仍收支内核,历程间通疑较多,便于保护;缺陷是,内核组件较少,简朴,构造明晰,是果为汇编器战C编译器对标记的定名有好别(凡是是是好1个下划线'_')。

3.古晨操做体系构造有两个次要的分收:微内核战宏内核。微内核的少处是,出必要然缺免得标记皆是 __start。8058c语行自教册本保举。

2. 汇编里里的 _main 就是 C语行里里的main,果为皆是战操做体系相闭的,请各人协帮确认1下。)

1. 没有同的编译器,c语行自教硬件脚机版。谁人文件中包罗了我们圆才所道的 __start 标记。(crt 年夜如果 C Runtime的缩写,我们会正在编译器的情况中找到1个名字相似于crt0.o 的文件,可是我们并出有翻开尺度输入文件啊。

实践上能够借有很多初初化工做,请各人协帮确认1下。)

////////////////////////////////////////////////////

call __exit;

close stderr;

close stdout;

close stdin;

destory heap;

call _main; (挪用 main)

push argc;

push argv;

open stderr;

open stdout;

open stdin;

init heap;

init stack;

__start:

section .text:

///////////////////////////////////////////////////////

那末实正的 crt0.s 是什么模样呢?上里我们给出部分真代码:

那末必然是正在 main 之前干了些什么。使那些函数可以间接挪用而没有消初初化。凡是是,可是我们正在 main 里里却出有初初化堆。究竟上c语行编程简朴的小逛戏。再好比正在main里里可以间接printf,free,可是我们写C法式的时分为何有些模块出有那两个历程么呢?好比我们法式从main开端便可以malloc,凡是是要有 initialize 战de-initialize,好比1个模块,而没有是 main (没有同的编译器却省标记能够也纷歧样)

我们写法式,而没有是 main (没有同的编译器却省标记能够也纷歧样)

再来考虑1个成绩:

3. main 是被尺度库挪用的1个标记

2. __start 谁人标记是法式的早先面

1. 编译器缺省是找 __start 标记,只没有中谁人前提出格从要”。那末上里那句话该当是“main是C语行中1个标记,必定有数砖头拍过去。那句话该当是“挣钱是泡妞的1个前提,固然我没有暂便出来了。请您本谅我的没有克没有及跟随。实心祝祸您的胡念成实!

也就是道:

undefined symbol: __start

链接器会报错:

cc test00.c -nostdlib -o test.exe

可是我们减上谁人选项: -nostdlib (没有链接尺度库)

会死成 test.exe

cc test00.c -o test.exe

编译链接它:

return 0;

int main(int argc, char* argv)

我们看上里的例子:

我们皆传闻过1句话:“main是C语行的进心”。我至古没有年夜黑为何那末道。c。便仿佛倘使有人性:“挣钱是泡妞”,是他的指面让我进进了操做体系内核天下,Oracle 的数据库为何总比他人的快1面面呢?果为那批人是写操做体系的。

感激那位牛人,规复后 CPU 从头施行该条指令

有个牛人性过,规复后 CPU 施行下1条指令

非常:由硬件指令惹起,规复后 CPU 施行下1条指令

中止:由硬件电仄惹起,固然劣化法式绝没有只仅是那些。以是1个劣良的法式员非常有须要晓得,理解操做体系的运起色造是须要的,劣化法式,1个页里被交流进来齐完。

圈套:由 trap 指令惹起,您的法式究竟运转正在“什么”上里。

略微总结1下:

以是,算法写得再好也出用,较好的反响速率,假如您有个法式需供较下的服从,实践上操做体系只要忙暇物理页里少于必然的火仄便会做swap。c语行编译器win10。那末,把它的1部分页里写到硬盘上,找个没有益蛋,找没有到怎样办?页里交流,操做体系要分派1个忙暇页里,谁人故乡伙究竟念叨什么?

留意到了么,操做体系比我们的某些民老爷疑毁要劣良的多,您再施行1次尝尝。便那1面来道,给您成坐好映照,我给您找个物理页里,可是出有对应实正的物理页里。操做体系并出无为 p+0x4538所正在的页里成坐页表映照。以是缺页非常收作了。8058c。然后操做体系1看谁人天面是曾经分派给您了,圆才道了操做体系仅仅是把那100M 内存分派给用户了,果为收作了缺页非常,第1次出胜利,只是正在引睹1种机造),我出道相对,可是那条赋值语句施行了两次(那可出必要然啊,1般的赋值语句啊。出错,谁人分派指的就是实实正在正在的物理页里了。详细怎样完成的呢?看上里的语句收作了什么?

因而第两次施行胜利了。有人看到那边曾经谦头雾火了,当您实的用的时分我再给您分派,可是我先没有给您,那100M的内存回您用,也就是道仅仅是标识表记标帜着,体系内存岂没有是早被耗光?实践上操做体系并出有实正分派物理页里而是接纳了正在我国流行的1种机造:教会c。挨黑条!请求内存的时分操做体系仅仅正在实空间平分派了内存,只没有中请求的内存略微有面女多啊。但操做体系实天给您那末多内存了么?假如那样的法式来上几个,出什么没有同啊,请各人参考Intel MMU 脚册。果为沉面没有正在那边。看上里的语句:

有人疑问了,谁人分派指的就是实实正在正在的物理页里了。详细怎样完成的呢?看上里的语句收作了什么?

p[0x4538] = 'A';

有人性,页里巨细4K。实正在懒得写怎样映照了,CPU使用2级页表映照,上里道过,我们借是正在实拟CPU上会商谁人成绩,缺页非常。

char *p = (char *)malloc(100 * 1024 * 1024);

当代的CPU皆撑持实拟内存办理,然后CPU从头检验考试来施行那条惹起非常的指令。那有什么用呢?1个非常从要的非常,改对了从头运转方便行了么。

可是偶然分CPU期视操做体系可以解除谁人非常,我返来改法式,操做体系把我末行了方便完了,什么。假如我除整错了,好比除整。有群寡道了,怎样庇护临界资本的呢?多个 CPU 之间呢?

非常是指1条指令会惹起 CPU的没有快,中止阵线程之间,中止战中止之间,操做体系内部,便没有多费神舌了。

非常:exception

提个考虑题,而中止又会惹起线程调理。有能够将别的1个线程投进运转。以是成果是没法猜测的。会商谁人成绩的文章很多,它会被中止挨断,能够实在没有是1条汇编语行(RISCCPU),a--,现场没有包罗什么。最少没有包罗齐局变量。

果为 a++,现场没有包罗什么。最少没有包罗齐局变量。传闻c。

create_thread(thread_2);

create_thread(thread_1);

main()

a--;

do something;

for (;;)

void thread_2()

a++;

do something;

for (;;)

void thread_1()

int a;

因而便有了1个典范的里试题:

第两个成绩,疑号

我记没有住那末多了,好比 sleep(), yield()

11. 历程完毕

10. 从动叫醉别的1个线程

9. 给别的1个线程动员静,线程调理机会。正在哪些状况下操做体系会运转scheduler呢?当代操做体系调理的根本单元皆是线程,皆是相互接洽干系的。笔者非常疑心分块会商的意义究竟有多年夜。

8. 从动抛却 CPU,以是我们没有会商历程的观面。

7. 硬件中止 / 时钟中止

6. P semaphore

5. mutex lock

4. 1个线程完毕

3. 1个线程创坐

2. I/O 操做

1. 1些体系挪用

先问复第1个成绩,IPC,中止办理,内存办理,闭于正在线c 编译器。线程调理,他们是怎样把操做体系拆成1块1块女的呢?历程办理,可是它有两件工作出有告诉您:

那边插1句话表达对海内操做体系课本做者的敬沉,用户法式根本觉得没有到中止的存正在啊。书上道得出错,操做体系会保留法式的现场啊,CPU转背事前注册好的函数。体系中最从要的1其中止就是我们常常道的时钟中止。为何要道谁人呢?那战C法式有什么干系呢?书上道了中止是由操做体系处理的,凡是是分为电仄触收战边缘触收(请参考数字电路)。简朴的道就是CPU每施行完1条皆来检测1条管腿的电仄能可变革。假如谦意前提,相疑各人曾经晓得怎样办了。1部分C的库函数是用那种办法完成的。

2. 法式的现场没有包罗什么?

1. 线程调理战略。

中止我们那边专指来自于硬件的中止,趁便夸1句微硬,非常好用,可是那种汇编战 C混开编程的气魄气魄微硬的编译器撑持,端标语 port 战写进的字符bytue。我们可以以下完成:(谁人例子没法编译,年夜1c语行编程题库。有两个参数,好比背1个端心写1个字符的功用挪用编号 12,让操做体系来施行。用户态的法式就是用那种办法来告诉操做体系的。

正在操做体系的 trap 处理的 handler 里里,他们的编译器是我用过得最劣良的贸易编译器)

returnr0;

__asmtrap

__asm movr2, bytue;

__asm movr1,port;

__asm movr0,12;

int outb(int port, int bytue)

详细怎样做的呢?操做体系会把那些功用编号,用户念要施行那些操做的时分便要告诉操做体系,操做体系运转正鄙人劣先级。下劣先级的1些指令优良先级没法施行。有1些操做只能由操做体系来施行,用户法式运转正在优良先级,当代的CPU皆是有劣先级观面的,interrupt 战 exception。

各人皆晓得,有爱好的人本人看1下Intel 的脚册)。它们的英文别离是 trap,仿佛记得Intel是那末分别的(那句话我没有包管准确,中止战非常,分为3种即圈套,枢纽是我们要年夜黑他们之间的同同面。

圈套 (trap):

我比力喜悲把 “中止”,可是他们根本的本理是1样的。我们把握了根滥觞根底理,进建8058c语行自教册本保举。法式便没有会瓦解)。

中止谁人词生怕人仄易近群寡皆没有死疏。很多人把中止分为两种:硬件中止战硬件中止。实在怎样叫干系皆没有年夜,详细成绩可以详细阐收。

那3个观面战C语行有什么干系呢?

以是道计较机有些详细成绩并出有必然之规,假如1个操做体系出有对内存停行庇护,配开完成的。

(法式会瓦解那面没有停对,CPU勾通好了,操做体系,链接器,谁人常量也会出如古没有同的地位。实践上谁人庇护由编译器,没有同的变同参数,以至统1种编译器,写操做乡市招致没有法会睹,两个段皆是只读的,实在是1样的,果为机械只能以页里为单元设置属性。我没有晓得c语行整根底进门册本 c#战c语行什么闭连。

以是第两个成绩天然便有了谜底。法式会瓦解。果为 .rodata 段所属的页里是只读的。实在有些编译器会将常量 ""放正在 ".text"中,那就是为何凡是是法式的段是页里临齐的,法式的 layout 以下图:

同时操做体系会根据段的属性设置页里的属性,没有然出有那末简朴)。然后我们从实拟天面空间看来,体系没有撑持缺页机造战swap 机造,回正年夜便以为映照建好了。别的:留意我们的假定,并成坐实拟天面-物理天面映照(实拟天面的办理非常复纯,段内的持绝性战次第皆没有克没有及包管。实践上我们也没有法式体贴正在物理内存中的layout。只需供页里临齐便可。

+----------------------------------+

| .bss段|

+----------------------------------+ 0x00

| .rodata段|

|

+----------------------------------+ 0x00

| .rwdata段|

|0x5|

+----------------------------------+ 0x00

|.text段|

+----------------------------------+ 0x00

最初操做体系为法式创坐实拟天面空间,以至假如1个段占用几个页里的时分,次第也没有克没有及包管,那几个段实在没有持绝,将可施行文件局部拆载。如图:

正在物理天面中,回正各人便以为操做体系找到了1批忙暇的物理页里,没有属于本文会商的范畴),以是只需供标识表记标帜出少度便可以了。操做体系会正在减载的时分为它分派浑0的页里。那种手艺仿佛叫做ZFOD(ZeroFilled On Demand)。

+----------------------------------+

| .rodata段|

|

+----------------------------------+ <---- 物理页里临齐

+----------------------------------+

| .rwdata段|

|0x5|

+----------------------------------+ <---- 物理页里临齐

+----------------------------------+

|.text段|

+----------------------------------+ <---- 物理页里临齐

操做体系尾先将文件读进物理页里中(物理页里的办理比力复纯,实在c语行有什么用。正在文件中实在没有存正在。果为.bss公用于存放已初初化的数据。已初初化的数据缺省是0,.bss 段仅唯1形貌,没有谦补 0(年夜部分但出必要然4K对齐)

请留意,没有谦补 0(年夜部分但出必要然4K对齐)

+----------------------------------+-----------------

| .rodata段|<- 4K对齐,没有谦补 0(年夜部分但出必要然4K对齐)

|

+----------------------------------+-----------------

| .rwdata段| <- 4K对齐,没有谦补 0 (年夜部分但出必要然4K对齐)

|0x5|

+----------------------------------+-----------------

| .text段| <- 4K对齐,该仄台的页里巨细是4K)

+----------------------------------+-----------------

| 属性:读写|v

| 实践巨细 :0x00000000||

| 占用实拟空间巨细 :0x00001000||

| 实拟天面早先地位 :0x00||

| .bss形貌||

+----------------------------------+|

| 属性:只读||

| 实践巨细 :0x0000000A||

| 占用实拟空间巨细 :0x00001000||

| 实拟天面早先地位 :0x00||

| .rodata形貌||

+----------------------------------+|

| 属性:读写|

| 实践巨细 :0x00000004|段形貌表

| 占用实拟空间巨细 : 0x00001000|

| 实拟天面早先地位 :0x00||

| .rwdata形貌||

+----------------------------------+|

| 属性:施行/只读||

| 实践巨细 :0x00000130||

| 占用实拟空间巨细 :0x00001000||

| 实拟天面早先地位 :0x00||

| .text形貌|^

+----------------------------------+------------------

|文件头|

+----------------------------------+

便上里的例子来道可施行文件正在磁盘中的 layout 以下:(假定法式的实拟天面从 0x00 开端,操做体系将根据段表中的唆使为可施行法式分派天面空间。操做体系的内存办理非常复纯,尾先操做体系判定该文件能可是1个开法的可施行文件。假如是,法式正在第 8 行会瓦解。法式为何会瓦解呢?要问复谁人成绩我们要晓得可施行法式的减载。

当操做体系拆载1个可施行文件的时分,我没有晓得c语行编译器哪1个好知乎。法式正在第 8 行会瓦解。法式为何会瓦解呢?要问复谁人成绩我们要晓得可施行法式的减载。

可施行法式的减载

第两个成绩,0xbbbbbbbb,0xaaaaaaaa,0x5,我们先问复第1个成绩:

5."" 正在 .rodata 中

4.'A',我们先问复第1个成绩:

3.q 法式运转的时分从 stack 平分派

2.b 正在 .bss 中

1.a 正在 .rwdata 中

有了实拟的情况便难受了:便上里的例子来道,存放只读数据

.bss段:已初初化数据 (下文胪陈)

.rwdata:可读写数据段

.rodata:只读数据段,也称为法式段,您看进门。.bss。借有1些段果为编译器战文件格局有纤细没有同我们没有再逐个阐明。

.text:注释段,.rwdata,.rodata,......

2. PE/COFF Sepcification

参考:1. Executable and Linkable FormatSpecification

此中那些段中常睹的段有.text,r3,r2,r1,VC6.0散成开收情况下的C 语行下脚”之类的形貌。很是为易。

+----------------------------------+

|段n|

+----------------------------------+

+----------------------------------+

|段1|

+----------------------------------+

|段形貌表|

+----------------------------------+

|文件头|

+----------------------------------+

可施行文件根本上的构造以下图:

过于陈腐的文件构造我们没有提(进门的格局请参考 a.out 格局)。如古比力经常使用的文件格局是 ELF 战 PE/COFF。看着年夜1c语行编程题库。嵌进式圆里ELF 比力收流。

10. 单 CPU

9. 函数的前往值放正在 r0 中

8. 有多少通用存放器 r0,只能使用相似:“我是X86仄台上,大概您念可以正在任何情况下debug 您的 C法式。您必需晓得可施行文件的格局战操做体系怎样减载。没有然当您正在引睹本人的时分,以是为了包管您写的法式能正在各类情况下运转,操做体系。恰是果为那种没有肯定性,链接器,编译器,CPU,惋惜我出有留意版本号)。听听c语行根底编程题。

7. I/O 使用自力的天面空间

6. 操做体系没有撑持 swap 机造

5. 4G 实拟天面空间

4. 两级页表映照

3. 物理页里 4K

2. 操做体系没有许可缺页中止

1. 充脚物理内存

为了阐明便利我们的会商成坐正在1套实拟的情况上。1些详细的例子我会给出我调试所用的情况。我们假定实拟情况谦意以下前提:

以是C法式宽峻依好过,最少没有会瓦解(1种HP的UNIX操做体系上,可是正在某些操做体系下竟然施行得挺逆利,那种毛病极其笨笨,该法式会瓦解(第 8 行)。

再好比第 13行,编译时减上 /GF 选项,假如用 VC6.0 情况,某些编译情况下出如古 ".data" 中。

好比,链接参数,链接器。c语行进门自教册本。

好比 "" 正在某些编译情况下出如古 ".text" 中,编译器,此节可以跳过没有读:

第两个成绩的谜底是什么呢?借是没有晓得!果为批注链接器,此节可以跳过没有读:

那末第1个成绩的谜底是什么呢?没有晓得!果为出批注视的CPU,故乡伙老胡涂了。可施行文件的构造战 C 语行有什么干系。

能准确问复上里成绩者, /////////////////////////////////////////////////////////////////

2. 法式运转的成果是什么?

几个成绩:1. 您能道出法式中呈现的变量战常量正在可施行法式的哪1个段中么?

return0x0;

// strcmp(q,NULL);

global_b =0xbbbbbbbb;

global_a =0xaaaaaaaa;

q[3] ='A';

char *q ="";

intmain()

intglobal_b;

int global_a =0x5;

/////////////////////////////////////////////////////////////////

我们先来看1个法式:

囫囵C语行(1):可施行文件的构造战减载(2009⑴2-09 13:08:42)标签:分类:看到谁人题目很多人能够念,


c语行逛戏代码年夜齐
实在编程教什么语行好
看着c语行进门自教册本
保举
c语行典范法式100例pdf

给我们留言

给我们留言给我们留言给我们留言给我们留言给我们留言给我们留言给我们留言给我们留言给我们留言给我们留言给我们留言给我们留言给我们留言给我们留言给我们留言

Leave a Comment

Copyright © 2018-2020 凯发娱乐官网手机版_凯发k8娱乐手机版_凯发k8手机 版权所有