计算机系统概论 作业4


  1. 某代码由 foo.cbar.c 构成. 内容如下:

    /* foo.c */ 
    void p2(void); 
    int main(){ 
    	p2(); 
    	return 0; 
    }
    /* bar.c */ 
    #include <stdio.h> 
    extern char main; 
    void p2(){ 
    	printf("0x%x\n", (int)main); 
    }

    ( 具体取决于编译器实现 )

    1) 请问能否正常联合编译? 如果可以联合编译则运行结果如何? 请说明你给出的回答的理由.

    答: 可以正常联合编译. 运行结果为编译后 main() 函数的地址. 因为 main 函数在 bar.c 中声明, 联合编译后 p2() 函数会输出变量 main 存储的值, 即编译后 main() 函数的地址.

    2) 如果去掉 bar.c 中的 extern 关键字, 能否正常联合编译? 如果可以联合编译则运行结果如何? 请说明你给出的回答的理由.

    答: 可以正常联合编译. 运行结果为编译后 main() 函数的地址. (因为 main 为强定义, 会覆盖未初始化的弱定义 char main, 链接时不在乎类型.) 删去之后联合编译, 会在 foo.c 中得到其定义, 联合编译后 p2() 函数会输出 main() 函数的地址.

  2. 对于如下代码 foo.c, 如果编译为 foo.o, 那么在 elf 文件的以下段中, 会出现哪些符号? (如果有多种合法分布情况, 则任意给出一种即可).

    3   extern int add(int a, int b); 
    4
    5   inline int process(int *v1, int *v2, int *v3) { 
    6       *v3 = add(*v1, *v2); 
    7   } 
    8 
    9   int a[100]; 
    10  extern int b[100]; 
    11  static int c[100]; 
    12 
    13  int total_process() {
    14      for (int i = 0;i < 100; i++) { 
    15          process(a+i, b+i, c+i); 
    16      } 
    17  }

    ( gcc 的内联函数需为 static inline. )

    .bss: a, b, c.
    .data: 无. 
    .text: total_process.
    .symtab: add, process, a, b, c.

    其中对于 total_process 函数中用到的符号, 哪些会在编译期被定位, 哪些会在链接期被定位?

    编译期定位的符号: i, total_process.
    链接期定位的符号: a, b, c.
  3. 下面的问题涉及虚拟地址转换为物理地址

    • 内存是字节可寻址的
    • 内存访问是针对 1 字节的字(即本题的 word 就是 1byte)
    • 虚拟地址 16 位宽 / 物理地址 14
    • 页面大小为 1024 字节
    • TLB4 路组相联 (4-way set associative), 共有 16 个表项

    在下表中, 所有数字都是十六进制的. 前 32 页的 TLB 和页表内容如下:

    1) 下面的框显示了虚拟地址的格式. 指出字段用于确定以下内容: VPO / VPN / TLBI / TLBT

    VPN: 15 - 10
    VPO: 9 - 0
    TLBI: 11 - 10
    TLBT: 15 - 12

    类似的标注出物理地址的格式: PPO / PPN

    PPN: 13 - 10
    PPO: 9 - 0

    2) 对于给定的两个虚拟地址 (0x2F090x0C53), 请分别表示出相应的 TLB 表项和物理地址, 并指出 TLB 是否命中、是否发生 page fault. 如 page fault, 请在 PPN 中输入 -, C 部分留白.

    答:

    0x2F09:

    A:
        Virtual Address:
        0010 1111 0000 1001
    B:
        VPN: 0x0B
        TLB Index: 0x3
        TLB Tag:0x2
        TLB Hit: No (注意这个 Hit!)
        Page Fault: Yes
        PPN: -
    C:
        Physical Address:
        留白.

    0x0C53:

    A:
        Virtual Address:
        0000 1100 0101 0011
    B:
        VPN: 0x03
        TLB Index: 0x3
        TLB Tag:0x0
        TLB Hit: Yes
        Page Fault: No
        PPN: 0xD
    C:
        Physical Address:
        11 0100 0101 0011
  4. 程序运行之前需要为程序分配对应的内存空间, 并为内存空间赋予一定的初始值和属性, 下表为 x86 架构下用户空间的内存映射关系. 请填写下表, 并说明可执行文件对应的段 (.data, .bss, .init, .rodata, .text) 段分别会被以什么属性映射到哪部分内存空间中.

    | 内存起始地址 | 内存类型 | 内存初始值 | 内存属性 |
    | :—————————: | :—————————: | :———————————————————-: | :—————: |
    | 0xFFFFFFFF | 内核地址 | 系统决定 | 不可读不可写 |
    | 0xC0000000 | 栈 | 0(默认) | 可读可写 |
    | 由可执行文件决定 | 共享库内存映射区 | 共享库文件与可执行文件决定 | 只读 |
    | 0x40000000 | 运行时堆空间 | 操作系统决定 | 可读可写 |
    | 由可执行文件决定 | 可读写数据段 | .data由可执行文件决定,
    .bss为 0
    | 可读可写 |
    | 由可执行文件决定 | 只读数据 | 可执行文件决定 | 只读 |
    | 0x08048000 | 保留内存地址 | | |

    .data:  可读可写  映射到可读写数据段.
    .bss:  可读可写  映射到可读写数据段.
    .text:  只读  映射到只读数据.

文章作者: Chengsx
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Chengsx !
  目录