C 语言相关内容省略,复习自用,仅供参考~
存储程序工作方式:将事先编好的程序和原始数据送入主存后才能执行程序,程序被启动执行后,计算机能在不需要操作人员干预下自动完成逐条指令取出和执行的任务。
程序执行过程:主存取指令
→
\to
→ 指令译码
→
\to
→ PC 自增
→
\to
→ 取操作数并执行
→
\to
→ 结果送往主存或寄存器。
单位时间完成的工作量:吞吐率,带宽;作业提交开始到完成所需的时间:响应时间,执行时间,等待时间或时延。
用户 CPU 时间
=
=
= 平均时钟周期数
×
\times
× 时钟周期
=
=
= 平均指令条数
×
\times
× CPI
×
\times
× 时钟周期.
时钟周期(ns)
=
1
/
=1/
=1/ 时钟频率(GHz);
1
1
1 GHz =
1
0
3
10^3
103 MHz
=
1
0
9
= 10^9
=109 Hz;
1
1
1 s =
1
0
9
10^9
109 ns.
CPI(执行一条指令所用的时钟周期)
=
=
= 平均时钟周期数
÷
\div
÷ 平均指令条数.
MIPS(平均每秒执行百万条指令数)
=
1
/
=1/
=1/ 时钟周期(ns)
÷
\div
÷ CPI
×
1
0
?
6
\times 10^{-6}
×10?6.
CPI 越低,时钟频率越高(即时钟周期越低)时,用户 CPU 时间越低(即CPU执行速度越快)。
峰值 MIPS 在 CPI 最低处。
整体改进后速度提升倍数 = 1 / ( =1/( =1/( 改进部分时间比例 / / / 改进部分速度提升倍数 + + + 未改进部分时间比例 ) ) ).
进制转换:
b
n
.
.
.
b
0
.
b
?
1
.
.
.
b
?
m
(
R
)
=
∑
i
=
?
m
n
b
n
R
n
(
10
)
,
m
,
n
>
0
{b_n...b_0.b_{-1}...b_{-m}}_{(R)}={\sum_{i=-m}^n b_nR^n}_{(10)}, m,n>0
bn?...b0?.b?1?...b?m?(R)?=∑i=?mn?bn?Rn(10)?,m,n>0.
2 进制
?
\Leftrightarrow
? 16 进制:4 位一组。
小端存储:
A
1
A
2
?
∣
?
B
1
B
2
?
∣
?
C
1
C
2
?
∣
?
D
1
D
2
→
D
1
D
2
C
1
C
2
B
1
B
2
A
1
A
2
(
16
)
A_1A_2\ | \ B_1B_2\ | \ C_1C_2\ | \ D_1D_2 \to {D_1D_2C_1C_2B_1B_2A_1A_2}_{(16)}
A1?A2??∣?B1?B2??∣?C1?C2??∣?D1?D2?→D1?D2?C1?C2?B1?B2?A1?A2?(16)?.
字长:ALU 内部的数据宽度。
补码:正数符号位为 0,数值为自身;负数符号位为1,数值为按位取反后末位加 1。
求反:
?
y
=
(
~
y
)
+
1
-y=(\sim y)+1
?y=(~y)+1,其中
~
\sim
~ 为按位取反。
加法器标志寄存器 | ZF 零标志 | OF 溢出标志 | SF 符号标志 | CF 进/错位标志 |
---|---|---|---|---|
0 | 结果不为 0 | 结果未溢出(有符号) | 结果为正 | 结果最高位发生进/错位;结果未溢出(无符号) |
1 | 结果为 0 | 结果发生溢出(有符号) | 结果为负 | 结果最高位无进/错位;结果发生溢出(无符号) |
减法时, x ? y = x + ( ( ~ y ) + 1 ) x-y=x+((\sim y)+1) x?y=x+((~y)+1) 中加法进位记为 C C C,则 C F = ! C CF=! C CF=!C,其中 ! ! ! 为逻辑非。
异号相加,同号相减时,永远不会溢出。
正溢出:正数
+
+
+ 正数
→
\to
→ 负数,即正数
?
-
? 负数
→
\to
→ 负数。
负溢出:负数
+
+
+ 负数
→
\to
→ 正数,即负数
?
-
? 正数
→
\to
→ 正数。
单精度值类型 | 符号(1位) | 阶码(8位,偏置127) | 尾数(23位) | 值 |
---|---|---|---|---|
规格化非零数 | 0 或 1 | 0 < e < 255 0<e<255 0<e<255 | 任意 | ( ? 1 ) s × 2 e ? 127 × ( 1. f ) (-1)^s\times2^{e-127}\times(1.f) (?1)s×2e?127×(1.f) |
正零 | 0 | 0 | 0 | + 0 +0 +0 |
负零 | 1 | 0 | 0 | ? 0 -0 ?0 |
正无穷大 | 0 | 全 1,即 255 ( 10 ) _{(10)} (10)? | 0 | + ∞ +\infty +∞ |
负无穷大 | 1 | 全 1 | 0 | ? ∞ -\infty ?∞ |
非规划化数 | 0 或 1 | 0 | 非 0 | 下溢, ( ? 1 ) s × 2 ? 126 × ( 0. f ) (-1)^s\times2^{-126}\times(0.f) (?1)s×2?126×(0.f) |
非数 | 0 或 1 | 全 1 | 非 0 | N a N NaN NaN |
(待更新~)
过程调用:内存分配,栈帧结构
运算还原
选择结构:switch-case实现 - 连续比较/数组/二分查找
循环结构:while/do-while/自增自减
数组
内存对齐
ELF 文件格式:ELF 头
+
+
+ .text 节(目标代码)
+
+
+ .rodata 节(只读数据)
+
+
+ .data 节(已初始化全局变量)
+
+
+ .bss 节(未初始化全局变量,占位符)
+
+
+ .symtab 符号表(函数名和非局部变量名)
+
+
+.rel.text 节(重定位)
+
+
+ .rel.data 节(重定位)
+
+
+ .debug 节(调试符号表)
+
+
+ .line 节(-g 选项)
+
+
+ .strtab 节(符号及节名)
+
+
+ 节头表。
可读写数据段: .data 节(已初始化全局变量)
+
+
+ .bss 节(未初始化全局变量,占位符)。
符号分类:全局 (非 static);外部(extern);本地(static)。
符号解析:强符号为函数名和已初始化全局变量名;弱符号为未初始化全局变量名;本地符号无强弱。
强符号只能定义一次;同时有强弱符号,符号类型以强符号为准,弱符号指向同一处地址;多个弱符号,任选其一。
// main.c
#include <stdio.h>
int d = 100;
int x = 200;
int y = 300;
void pi(void);
int main() {
y = 0;
p1();
printf("d=%d, x=%d, y=%d\n", d, x, y);
return 0;
}
// p1.c
double d;
short y;
void p1(void) {
d = 1.0;
y = -100;
}
gcc -m32 -o linktest main.c p1.c
./linktest
>>> d=0, x=1072693248, y = 65436
d
=
d=
d= 1.0 (double, 64 bit)
→
\to
→ 00 00 00 00
∣
|
∣ 00 00 F0 3F (小端)
→
x
=
\to x=
→x= 3FF00000H (大端),
d
=
d=
d= 0
→
x
=
\to x=
→x= 1072693248,
d
=
d=
d= 0.
y
=
y=
y= -100 (short, 16bit)
→
\to
→ 1001 1100 1111 1111 (补)
→
\to
→ 11 11 11 11 11 11 11 00 11 01 10
∣
|
∣ 00 00 … (小端)
→
\to
→ 65436
(
10
)
_{(10)}
(10)?.