一、变量的声明
全局变量声明
int a,b,c;//在函数外声明的变量都是全局变量
void fun1(){
a=10;
b=20;
c=a;
}
void fun2(){
int a=10,b=20; // mov [a (02BC46Ch)],0Ah; mov [b(02BC470h)],14h; mov [c (02BC474h) ],1Eh;
int c = a;
}
局部变量声明
void fun3(){
int a,b;
a=10,b=20;//mov [ebp-8],0xA; mov [ebp-14h],14h;
//缓冲区中局部变量的存储位置是随机,并不是从紧密相邻或者有规律的
- [ ] (可以想想如果是随机的话,存储了第一个变量后,第二个变量是如何做到不覆盖第一个变量的值?)
}
声明总结
1、声明的动作就是让计算机分配一块内存,然后把相关内容存到这里,所以像基本的数据类型都是在告诉计算机应该给每部分数据分配多大的空间;像结构体,共用体那些复合类型只是分配的空间更大一些罢了(此处留个疑问:以结构体为例,如果只是定义了结构体,在使用结构体定义对象之前,编译器会给结构体分配内存空间吗?)
2、全局变量声明未赋值,此时默认值是0;
二、类型转换(数据宽度的转换)
MOVSX 带符号扩展,在传送值;(这条指令只用于有符号整数)
//符号扩展的意思是,当计算机存储某一个有符号数时,符号位位于该数的第一位,所以,
//当扩展一个负数的时候需要将扩展的高位全赋为1.对于正数而言,符号扩展和零扩展MOVZX是一样的,将扩展的高位全赋为0.
mov al,0ffh;
movsx cx,al;
mov al,80h
movsx cx,al;
/*
例子:MOV BL,80H
MOVSX AX,BL
//AX == 0FF80H
可能初学者奇怪80H不是正数吗?FF怎么来的?看下面,
80h = 1000 0000 最高位为符号位, 即符号位为1
则MOVSX AX, BL后, AX = 1111 1111 1000 0000 = FF80h
MOVSX reg32, reg/mem8
MOVSX reg32, reg/mem16
MOVSX reg16, reg/mem8
*/
MOVZX全零扩展并传送)将源操作数复制到目的操作数,并把目的操作数 0 扩展到 16 位或 32 位。这条指令只用于无符号整数
- MOVZX不用像MOVSX哪样,先判断符号,再填充,MOVZX直接用0来填充
mov al,0ffh
movzx cx,al
mov al,80
movzx cx,al
/*
MOVZX reg32,reg/mem8
MOVZX reg32,reg/mem16
MOVZX reg16,reg/mem8
*/
关键点:有符号数+无符号数,结果是有符号还是无符号?
解:仍然是那句,计算机不管有无符号,只要保证操作对象的宽度一样,计算出来的结果如果存到有符号的容器,那么就是有符号;如果存到无符号的容器,那就是无符号;
三、表达式、语句的理解
四、参数与返回值的理解
六、运算符
关系运算符:
== != >= <= > <
逻辑运算符&& || !
void fun(int x,int y,int z){
if(x>1 && y>1 && z>1){
/*
00441A01 cmp dword ptr [ebp+8],1
00441A05 jle 00441A22
00441A07 cmp dword ptr [ebp+0Ch],1
00441A0B jle 00441A22
00441A0D cmp dword ptr [ebp+10h],1
00441A11 jle 00441A22
*/
printf("ok");
/*
00441A13 push 447B60h
00441A18 call 004410D7
00441A1D add esp,4
*/
}
//00441A20 jmp 00441A2F
else{
printf("error");
/*
00441A22 push 447B64h
00441A27 call 004410D7
00441A2C add esp,4
*/
}
}
void fun(int x,int y,int z){
if(x>1 || y>1 || z>1){
/*
00641A01 cmp dword ptr [ebp+8],1
00641A05 jg 00641A13
00641A07 cmp dword ptr [ebp+0Ch],1
00641A0B jg 00641A13
00641A0D cmp dword ptr [ebp+10h],1
00641A11 jle 00641A22
*/
printf("ok");
/*
00641A13 push 647B60h
00641A18 call 006410D7
00641A1D add esp,4
*/
}
//00641A20 jmp 00641A2F
else{
printf("error");
/*
00641A22 push 647B64h
00641A27 call 006410D7
00641A2C add esp,4
*/
}
}```
## 单目和三目运算符
```c
void fun(int x,int y,int z){
int i=10;
//00CE1A85 mov dword ptr [ebp-8],0Ah
int k=++i;
/*
00CE1A8C mov eax,dword ptr [ebp-8]
00CE1A8F add eax,1
00CE1A92 mov dword ptr [ebp-8],eax
00CE1A95 mov ecx,dword ptr [ebp-8]
00CE1A98 mov dword ptr [ebp-14h],ecx
*/
int h=i++;
/*
00751A8B mov eax,dword ptr [ebp-8]
00751A8E mov dword ptr [ebp-20h],eax
00751A91 mov ecx,dword ptr [ebp-8]
00751A94 add ecx,1
00751A97 mov dword ptr [ebp-8],ecx
*/
int m = x > y ? x : y;
/*
00383C6A mov eax,dword ptr [ebp+8]
00383C6D cmp eax,dword ptr [ebp+0Ch]
00383C70 jle 00383C7D
00383C72 mov ecx,dword ptr [ebp+8]
00383C75 mov dword ptr [ebp+FFFFFF0Ch],ecx
00383C7B jmp 00383C86
00383C7D mov edx,dword ptr [ebp+0Ch]
00383C80 mov dword ptr [ebp+FFFFFF0Ch],edx
00383C86 mov eax,dword ptr [ebp+FFFFFF0Ch]
00383C8C mov dword ptr [ebp-2Ch],eax
*/
printf("i=%d\t\tk=%d\t\th=%d\t\tm=%d\n", i,k,h,m);
}