| 种类 | 功能 |
|---|---|
| 累加寄存器 | 存储运行的数据和运算后的数据。 |
| 标志寄存器 | 用于反应处理器的状态和运算结果的某些特征以及控制指令的执行。 |
| 程序计数器 | 程序计数器是用于存放下一条指令所在单元的地址的地方。 |
| 基址寄存器 | 存储数据内存的起始位置 |
| 变址寄存器 | 存储基址寄存器的相对地址 |
| 通用寄存器 | 存储任意数据 |
| 指令寄存器 | 储存正在被运行的指令,CPU内部使用,程序员无法对该寄存器进行读写 |
| 栈寄存器 | 存储栈区域的起始位置 |
不过要注意一点,最终磁盘的存储都是以8位为一个字节来保存文件的。
bcc32
-c
-S
Sample4
.c
.
386p
ifdef ??version
if ??version GT
500H
.mmx
endif
endif
model flat
ifndef ??version
?debug macro
endm
endif
?debug S
"Sample4.c"
?debug T
"Sample4.c"
_TEXT segment dword public use32
'CODE'
_TEXT ends
_DATA segment dword public use32
'DATA'
_DATA ends
_BSS segment dword public use32
'BSS'
_BSS ends
DGROUP group _BSS,_DATA
_TEXT segment dword public use32
'CODE'
_AddNum proc near
?live1@0:
;
;
int AddNum(
int a,
int b){
;
push ebp
mov ebp,esp
;
;
;
return a + b;
;
@1:
mov eax,dword ptr [ebp+
8]
add eax,dword ptr [ebp+
12]
;
; }
;
@3:
@2:
pop ebp
ret
_AddNum endp
_MyFunc proc near
?live1@48:
;
; void MyFunc(){
;
push ebp
mov ebp,esp
;
;
int c;
; c = AddNum(
123,
456);
;
@4:
push
456
push
123
call _AddNum
add esp,
8
;
; }
;
@5:
pop ebp
ret
_MyFunc endp
_TEXT ends
public _AddNum
public _MyFunc
?debug D
"Sample4.c"
20343
45835
end
_TEXT segment dword
public use32
'CODE'
_TEXT ends
_DATA segment dword
public use32
'DATA'
_DATA ends
_BSS segment dword
public use32
'BSS'
_BSS ends
DGROUP group _BSS,_DATA
_AddNum proc
near
_AddNum endp
_MyFunc proc
near
_MyFunc endp
_TEXT ends
end
_TEXT segment dword public use32 'CODE'
_TEXT ends
_DATA segment dword public use32 'DATA'
_DATA ends
_BSS segment dword public use32 'BSS'
_BSS ends
段定义( segment ) 是用来区分或者划分范围区域的意思。汇编语言的 segment 伪指令表示段定义的起始,ends 伪指令表示段定义的结束。段定义是一段连续的内存空间
DGROUP
group _BSS,_DATA
_TEXT segment dword public use32 'CODE'
_TEXT ends
因此,即使在源代码中指令和数据是混杂编写的,经过编译和汇编后,也会转换成为规整的本地代码。
_AddNum proc
near
_AddNum endp
_MyFunc proc
near
_MyFunc endp
mov ebp,esp
mov eax,dword ptr
[ebp+8]
// 定义被初始化的全局变量
int a1 =
1;
int a2 =
2;
int a3 =
3;
int a4 =
4;
int a5 =
5;
// 定义没有初始化的全局变量
int b1,b2,b3,b4,b5;
// 定义函数
void MyFunc(){
// 定义局部变量
int c1,c2,c3,c4,c5,c6,c7,c8,c9,c10;
// 给局部变量赋值
c1 =
1;
c2 =
2;
c3 =
3;
c4 =
4;
c5 =
5;
c6 =
6;
c7 =
7;
c8 =
8;
c9 =
9;
c10 =
10;
// 把局部变量赋值给全局变量
a1 = c1;
a2 = c2;
a3 = c3;
a4 = c4;
a5 = c5;
b1 = c6;
b2 = c7;
b3 = c8;
b4 = c9;
b5 = c10;
}
_DATA segment dword
public use32
'DATA'
align
4
_a1
label dword
dd
1
align
4
_a2
label dword
dd
2
align
4
_a3
label dword
dd
3
align
4
_a4
label dword
dd
4
align
4
_a5
label dword
dd
5
_DATA ends
_BSS segment dword
public use32
'BSS'
align
4
_b1
label dword
db
4 dup(?)
align
4
_b2
label dword
db
4 dup(?)
align
4
_b3
label dword
db
4 dup(?)
align
4
_b4
label dword
db
4 dup(?)
align
4
_b5
label dword
db
4 dup(?)
_BSS ends
_TEXT segment dword
public use32
'CODE'
_MyFunc proc
near
push ebp
mov ebp,esp
add esp,-
20
push ebx
push esi
mov eax,
1
mov edx,
2
mov ecx,
3
mov ebx,
4
mov esi,
5
mov dword ptr [ebp-
4],
6
mov dword ptr [ebp-
8],
7
mov dword ptr [ebp-
12],
8
mov dword ptr [ebp-
16],
9
mov dword ptr [ebp-
20],
10
mov dword ptr [_a1],eax
mov dword ptr [_a2],edx
mov dword ptr [_a3],ecx
mov dword ptr [_a4],ebx
mov dword ptr [_a5],esi
mov eax,dword ptr [ebp-
4]
mov dword ptr [_b1],eax
mov edx,dword ptr [ebp-
8]
mov dword ptr [_b2],edx
mov ecx,dword ptr [ebp-
12]
mov dword ptr [_b3],ecx
mov eax,dword ptr [ebp-
16]
mov dword ptr [_b4],eax
mov edx,dword ptr [ebp-
20]
mov dword ptr [_b5],edx
pop esi
pop ebx
mov esp,ebp
pop ebp
ret
_MyFunc endp
_TEXT ends
_DATA segment dword
public use32
'DATA'
...
_DATA ends
_BSS segment dword
public use32
'BSS'
...
_BSS ends
_TEXT segment dword
public use32
'CODE'
_MyFunc proc
near
...
_MyFunc endp
_TEXT ends
注意:db 4 dup(?) 不要和 dd 4 混淆了,前者表示的是4个长度是1字节的内存空间。而 db 4 表示的则是双字节( = 4 字节) 的内存空间中存储的值是 4
mov
dword
ptr
[ebp-4],6
mov
dword
ptr
[ebp-8],7
mov
dword
ptr
[ebp-12],8
mov
dword
ptr
[ebp-16],9
mov
dword
ptr
[ebp-20],10
// 定义MySub 函数
void MySub(){
// 不做任何处理
}
// 定义MyFunc 函数
void Myfunc(){
int i;
for(int i = 0;i < 10;i++){
// 重复调用MySub十次
MySub();
}
}
上述代码将局部变量 i 作为循环条件,循环调用十次MySub 函数,下面是它主要的汇编代码
xor
ebx,
ebx ; 将寄存器清0
@
4 call _MySub ; 调用
MySub函数
inc
ebx ;
ebx寄存器的值 + 1
cmp
ebx,10 ; 将
ebx寄存器的值和10进行比较
jl
short @
4 ; 如果小于10就跳转到 @
4
XOR 指的就是异或操作,它的运算规则是 如果a、b两个值不相同,则异或结果为1。如果a、b两个值相同,异或结果为0。 相同数值进行 XOR 运算,运算结果为0。XOR 的运算规则是,值不同时结果为1,值相同时结果为0。例如 01010101 和 01010101 进行运算,就会分别对各个数字位进行 XOR 运算。因为每个数字位都相同,所以运算结果为0。
这里需要知道 i++ 和 ++i 的区别 i++ 是先赋值,复制完成后再对 i执行 + 1 操作 ++i 是先进行 +1 操作,完成后再进行赋值
i ^= i;
L4: MySub();
i++;
if(i <
10)
goto L4;
// 定义MySub1 函数
void MySub1(){
// 不做任何处理
}
// 定义MySub2 函数
void MySub2(){
// 不做任何处理
}
// 定义MySub3 函数
void MySub3(){
// 不做任何处理
}
// 定义MyFunc 函数
void MyFunc(){
int a =
123;
// 根据条件调用不同的函数
if(a >
100){
MySub1();
}
else
if(a <
50){
MySub2();
}
else
{
MySub3();
}
}
_MyFunc proc near
push ebp
mov ebp,esp
mov eax,
123 ; 把
123存入 eax 寄存器中
cmp eax,
100 ; 把 eax 寄存器的值同
100进行比较
jle short @8 ; 比
100小时,跳转到@8标签
call _MySub1 ; 调用MySub1函数
jmp short @11 ; 跳转到@11标签
@8:
cmp eax,
50 ; 把 eax 寄存器的值同
50进行比较
jge short @10 ; 比
50大时,跳转到@10标签
call _MySub2 ; 调用MySub2函数
jmp short @11 ; 跳转到@11标签
@10:
call _MySub3 ; 调用MySub3函数
@11:
pop ebp
ret
_MyFunc endp
// 定义全局变量
int counter =
100;
// 定义MyFunc1()
void MyFunc(){
counter *=
2;
}
// 定义MyFunc2()
void MyFunc2(){
counter *=
2;
}
mov
eax,
dword
ptr
[_counter] ; 将
counter 的值读入
eax 寄存器
add
eax,
eax ; 将
eax 寄存器的值扩大2倍。
mov
dword
ptr
[_counter],
eax ; 将
eax 寄存器的值存入
counter 中。
文章参考
https://www.computerhope.com/jargon/m/memory.htm
https://baike.baidu.com/item/队列/14580481?fr=aladdin
https://baike.baidu.com/item/栈/12808149?fr=aladdin
https://baike.baidu.com/item/环形缓冲器/22701730?fr=aladdin
《程序是怎样跑起来的》
https://baike.baidu.com/item/汇编语言/61826?fr=aladdin
https://baike.baidu.com/item/Windows操作系统/852149?fr=aladdin
磁盘
磁盘缓存
虚拟内存
https://baike.baidu.com/item/压缩算法/2762648
https://en.wikipedia.org/wiki/Central_processing_unit
https://www.digitaltrends.com/computing/what-is-a-cpu/
https://baike.baidu.com/item/寄存器/187682?fr=aladdin
https://baike.baidu.com/item/内存/103614?fr=aladdin
https://blog.csdn.net/mark_lq/article/details/44245423
https://baike.baidu.com/item/程序计数器/3219536?fr=aladdin
https://zhidao.baidu.com/question/124425422.html
☞中国开发者真实画像:Java长盛,偏爱Windows操作系统,鲜少参与开源项目
☞新冠全球蔓延,AI+大数据拿什么拯救全人类? | AI 技术生态论
☞无需3D运动数据训练,最新人体姿势估计方法达到SOTA | CVPR 2020
☞从哈希函数、哈希冲突、开散列出发,一文告诉你哈希思想与哈希表构造到底是什么!