下一页 上一页 目录

10. 实用技巧

10.1 栈和堆

概述

这里我们查看 "栈" 和 "堆" 是如何在内存中分配的

内存分配

FF..        |                 | <-- bottom of the stack
       /|\  |                 |   | 
 higher |   |                 |   |   stack
 values |   |                 |  \|/  growing
            |                 |
XX..        |                 | <-- top of the stack [Stack Pointer]
            |                 |
            |                 |
            |                 |
00..        |_________________| <-- end of stack [Stack Segment]
                 
                   Stack

内存地址值从 00.. 开始 (这也是堆栈段开始的地方),并向 FF.. 值增长。

XX.. 是堆栈指针的实际值。

函数使用堆栈用于

  1. 全局变量
  2. 局部变量
  3. 返回地址

例如,对于一个典型的函数

 |int foo_function (parameter_1, parameter_2, ..., parameter_n) {
    |variable_1 declaration;
    |variable_2 declaration;
      ..
    |variable_n declaration;
   
    |// Body function
    |dynamic variable_1 declaration;
    |dynamic variable_2 declaration;
     ..
    |dynamic variable_n declaration;
   
    |// Code is inside Code Segment, not Data/Stack segment!
    
    |return (ret-type) value; // often it is inside some register, for i386 eax register is used.
 |}
we have

          |                       |
          | 1. parameter_1 pushed | \
    S     | 2. parameter_2 pushed |  | Before 
    T     | ...................   |  | the calling
    A     | n. parameter_n pushed | /
    C     | ** Return address **  | -- Calling
    K     | 1. local variable_1   | \ 
          | 2. local variable_2   |  | After
          | .................     |  | the calling
          | n. local variable_n   | /
          |                       | 
         ...                     ...   Free
         ...                     ...   stack
          |                       |
    H     | n. dynamic variable_n | \
    E     | ...................   |  | Allocated by
    A     | 2. dynamic variable_2 |  | malloc & kmalloc
    P     | 1. dynamic variable_1 | /
          |_______________________|
        
            Typical stack usage
 
Note: variables order can be different depending on hardware architecture.

10.2 应用程序 vs 进程

基本定义

我们必须区分 2 个概念

进程通常也称为任务或线程。

10.3 锁

概述

2 种锁

  1. CPU内部
  2. CPU之间

10.4 写时复制

写时复制是一种用于减少内存使用的机制。它延迟内存分配,直到真正需要内存时才分配。

例如,当一个任务执行 "fork()" 系统调用 (以创建另一个任务) 时,我们仍然使用与父进程相同的内存页,处于只读模式。当一个任务写入页面时,它会引起异常,并且该页面会被复制并标记为 "rw" (读,写)。

 
1-) Page X is shared between Task Parent and Task Child
 Task Parent
 |         | RO Access  ______
 |         |---------->|Page X|    
 |_________|           |______|
                          /|\
                           |
 Task Child                | 
 |         | RO Access     |  
 |         |----------------                
 |_________| 
 
 
2-) Write request
 Task Parent
 |         | RO Access  ______
 |         |---------->|Page X|    Trying to write
 |_________|           |______|
                          /|\
                           |
 Task Child                | 
 |         | RO Access     |  
 |         |----------------                
 |_________| 
 
 
3-) Final Configuration: Either Task Parent and Task Child have an independent copy of the Page, X and Y
 Task Parent
 |         | RW Access  ______
 |         |---------->|Page X|    
 |_________|           |______|
              
              
 Task Child
 |         | RW Access  ______
 |         |---------->|Page Y|    
 |_________|           |______|

下一页 上一页 目录