从汇编角度理解正向编程

一、变量的声明

全局变量声明

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);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值