😇😇😇
CH1
编译
从源文件到目标文件的转化是由编译器驱动程序完成的,也就是常说的。
编译系统():预处理器编译器汇编器链接器
win环境的整个过程如下:
1
| 1.c -> 1.i -> 1.s -> 1.o -> 1.exe
|
1.exe
是我们常说的可执行文件,可以被加载到内存中,由系统执行。
shell
运行hello
程序
1 2 3 4 5
| #include<stdio.h> int main(){ printf("hello world\n"); return 0 ; }
|
初始时,shell程序执行它自己的指令,之后等待我们输入命令。当我们在键盘上输入字符串./hello
后,shell程序逐一将字符读入寄存器,再放入内存中。
下一步就是敲回车键,敲完后,shell程序就知道我们结束了命令的输入,然后shell执行一系列指令来加载可执行的hello文件,这些指令将hello目标文件中的代码和数据从 [磁盘] 复制到 [主存],数据包括最后输出的字符串hello,world\n
。
一旦目标文件中的代码和数据被加载到主存(DRAM),处理器就开始执行hello程序中的main函数里的机器语言指令。这些指令将hello,world\n
字符串中的字节从主存复制到寄存器文件,再从寄存器文件中复制到显示设备,最后到屏幕上。
高速缓存(SRAM)
抽象
文件
I/O设备文件
虚拟内存
主存、磁盘I/O设备虚拟内存
虚拟内存为每一个进程提供了一种假象,即每个进程都在独占地使用主存。这样一来,每一个进程看到的内存都是一致的,就叫虚拟地址空间。
进程
处理器、主存、I/O设备进程
进程是OS对一个正在运行的程序的一种抽象,OS实现交错的机制是上下文切换。
并发与并行
并发:同时具有多个活动的系统
并行:用并发使得系统更快
CH2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
#include<stdio.h> typedef unsigned char* byte_pointer ;
int is_little_endian(){ int test = 0x11 ; byte_pointer p = (byte_pointer)& test ; if(p[0] == 0x11){ return 1 ; }else{ return 0 ; } }
int main(){ if(is_little_endian){ printf("little_endian\n"); }else{ printf("big_endian\n"); } return 0 ; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| #include<stdio.h> #include<stdlib.h>
typedef unsigned char* byte_pointer ; int main(void){ int x = 0x89ABCDEF ; int y = 0x76543210 ; byte_pointer x_array = (byte_pointer)& x ; printf("%.2X \n",x_array[0]); byte_pointer y_array = (byte_pointer)& y ; int* res = (int*)malloc(sizeof(int)*4) ; for (int i = 3; i >= 1; i--) { res[i] = y_array[i] ; } res[0] = x_array[0] ; printf("0X"); for (int i = 0; i <= 3; i++) { printf("%.2X",res[3-i]); } return 0 ; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| #include<stdio.h> typedef unsigned char* byte_pointer ; size_t numCombine(size_t x,size_t y){ size_t mask = 0xff ; size_t result = ((x&mask)|(y&~mask)); return result ; } int main(){ size_t x , y ; scanf("%x",&x); scanf("%x",&y); printf("%.2X",numCombine(x,y)); return 0 ; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| #include<stdio.h> typedef unsigned char* byte_pointer;
unsigned replace_byte(unsigned x,int i,unsigned char b){ byte_pointer p = (byte_pointer)&x ; *(p+i) = b ; unsigned res = *((unsigned*)p) ; return res ; }
int main(){ printf("0x%.2X\n",replace_byte(0x12345678,2,0xAB)) ; return 0 ; }
|