C是怎么变成汇编的

C是怎么变成汇编的

C代码需要经过编译器编辑才能成为执行文件(二进制)。编译器是怎么做到的呢?
C代码 --> 编译器语法检查 --> 编译器转成汇编 --> … --> 二进制文件
在了解前,需要先了解下面的知识,自然就知道了

1、什么是裸函数?

//先看一下裸函数怎么写,这个裸函数中什么都没有做,编译器编译的时候,
//也不会做任何事,那下一步就不知道做什么事了,于是就会报错
void __declspec(naked) Function()  			
{...}			
		
上面的函数调用时,为什么会出错?			
		
//该裸函数,什么也没做,但是最后ret了,编译器编译的时候,汇编就会是ret
//于是就不会报错	
void __declspec(naked) Function()  			
{						
	__asm 
	ret		
}	

2、无参数无返回值的函数框架

void __declspec(naked) Function()  					
{					
	__asm				
	{				
		push ebp			          // 开栈
		mov ebp,esp			
		sub esp,0x40			
		
		push ebx			        //保护现场
		push esi			
		push edi
					
		lea edi,dword ptr ds:[ebp-0x40]			//为缓冲器填充数据 (int 3)
		mov eax,0xCCCCCCCC			
		mov ecx,0x10			
		rep stosd			
					
		pop edi			             //恢复堆栈                                
		pop esi			
		pop ebx			
		
		mov esp,ebp		           //降低堆栈
		pop ebp			
					
		ret			        //函数返回
	}				
}					

3、有参数有返回值的函数框架

int __declspec(naked) Function(int x,int y)  					
{					
	__asm				
	{				
		push ebp				   // 开栈	
		mov ebp,esp			
		sub esp,0x40	
				
		push ebx			 //恢复堆栈
		push esi			
		push edi
					
		lea edi,dword ptr ds:[ebp-0x40]	    //为缓冲器填充数据 (int 3)		
		mov eax,0xCCCCCCCC			
		mov ecx,0x10			
		rep stosd			
					
		mov eax,dword ptr ds:[ebp+8]		 // x,y两个数相加,这里x,y已经在进入函数前放入到了dword ptr ds:[ebp+8] dword ptr ds:[ebp+0xC]
		add eax,dword ptr ds:[ebp+0xC]			
					
		pop edi			
		pop esi			
		pop ebx			
		
		mov esp,ebp			
		pop ebp			
					
		ret			
	}				
}					

4、带局部变量的函数框架

int __declspec(naked) Function(int x,int y)  					
{					
	__asm				
	{				
		push ebp			
		mov ebp,esp			
		sub esp,0x40			
		
		push ebx			
		push esi			
		push edi			
		
		lea edi,dword ptr ds:[ebp-0x40]			
		mov eax,0xCCCCCCCC			
		mov ecx,0x10			
		rep stosd			
		
		mov dword ptr ds:[ebp-4],2			  //函数局部变量存放
		mov dword ptr ds:[ebp-8],3			
					
		mov eax,dword ptr ds:[ebp+8]	    //函数外部变量(x,y)相加
		add eax,dword ptr ds:[ebp+0xC]			
					
		pop edi			
		pop esi			
		pop ebx			

		mov esp,ebp			
		pop ebp			
					
		ret			
	}				
}					
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
一、问题描述 课题1:排序。要求从键盘上输入若干个人名,当输入完毕后,能显示正确的顺序。 课题2:编写一个类似于TT的英文打字测试程序。要求输入的字符能在屏幕上显示并报告所用时间。 二、设计思想 课题1:排序。程序分3个部分 (1) 等待用户输入数个人名,即输入字符串。本程序设定输入人名数为5到15个,运用了2个函数(input1,input2)实现。 定义 data1 db 21,0,22 dup('$') ;用于存放第一个字符串 data2 db 21,0,22 dup('$') ;用于存放第二个字符串 data3 db 21,0,22 dup('$') ;用于存放第三个字符串 data4 db 21,0,22 dup('$') ;用于存放第四个字符串 data5 db 21,0,22 dup('$') ;用于存放第五个字符串 data6 db 21,0,22 dup('$') ;用于存放第六个字符串 data7 db 21,0,22 dup('$') ;用于存放第七个字符串 data8 db 21,0,22 dup('$') ;用于存放第八个字符串 data9 db 21,0,22 dup('$') ;用于存放第九个字符串 dataa db 21,0,22 dup('$') ;用于存放第十个字符串 datab db 21,0,22 dup('$') ;用于存放第十一个字符串 datac db 21,0,22 dup('$') ;用于存放第十二个字符串 datad db 21,0,22 dup('$') ;用于存放第十三个字符串 datae db 21,0,22 dup('$') ;用于存放第十四个字符串 dataf db 21,0,22 dup('$') ;用于存放第十五个字符串 input1实现前五个字符串的输入,调用0A号功能实现输入,当用户没有输入字符而直接回车时,程序会判断为输入错误,直到输入字符为止,此时按下回车,会转到下个字符串的输入。 input2实现后10个字符串的输入,调用0a号功能实现输入,当用户没有输入字符而直接回车时,程序会判断用户选择结束输入,跳转出input2函数。实现了用户连续按两下回车(注意:第一个回车为前一个字符串的结束回车,此后再按一次回车就表示退出),直接退出输入的功能。 (2)人名排序,即字符串排序。 采用冒泡排序的方法,进行双重循环,内循环实现字符串的比较交换,若前一 个字符串大则跳转去交换,小或者相等则跳转去比较下两个字符串。 外循环是在内部循环结束后继续从第一个字符串开始跳转到内部循环,保证顺序排好。 另外字符串本身的比较也是一重循环,以字符串结尾符号'$'控制比较次数。 交换部分则是两个存储单元的完全交换(从第一个字符到最后一个字符)。 (3)输出排序好的人名 最后将排序好的字符串依次输出在屏幕上。 三、课程设计体会 在此次课程设计中,我与吕鑫等人一组,我们综合利用了80X86汇编语言程序设计这门课中所学的所有知识,实践操作了多种指令的功能,丰富了用汇编语言编程的经验。也从中体会到了用汇编编程的难处。 在以小组为单位的课程设计制作过程中,我与其他组员相互讨论、配合,最后共同完成了2个课题要求的程序编写,极大提升了我团队共同合作的编程经验,受益匪浅。也提高了我分析问题、解决问题的能力。 课题2:TT英文打字测试程序要求程序有3功能 (1)在屏幕上输出一条字符串; 在程序中定义几段字符串 STR1 DB 'ABCD EFGH IJKL MNOP QRST UVWX YZ.' STR2 DB 'THERE ARE SOME NEWSPAPERS ON THE TABLE.' STR3 DB 'THERE ARE SOME CLOUDS IN THE SKY.' STR4 DB 'SHE ALWAYS EATS HER LUNCH AT NOON.' STR5 DB 'I DO NOT LIKE AUTUMN AND WINTER.' 运行时,在屏幕上依次输出这几段字符串,每输出一段字符串,便开始等待用户从键盘输入字符。 (2)从键盘上读入字符,并显示在屏幕上,以回车键结束输入; 首先用 INT 21H 从键盘读入一个字符,将读入的字符放入AL中,判断该字符是否是回车,若不是回车则马上用INT 10H 在当前光标位置上显示AL中的字符,若是回车则结束从键盘上读入字符。 (3)对从键盘上读入字符的过程计时,并在输入结束后,将输入用时显示在屏幕上。 定义 SEC DW 0 ;sec表示秒钟 MIN DW 0 ;min表示分钟 HOURS DW 0 ;hours表示小时 将它们初始化为0。 输入字符结束后,依次将hours、min、mours赋值给ax,并输出在屏幕上,以分号隔开。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值