汇编语言与C/C的混合编程.ppt
第7章 汇编语言与CC+的混合编程,2,教学重点,第7章介绍实际应用当中,常见的混合编程问题,重点是参数传递方法混合编程的两种方式模块连接的约定规则模块连接的参数传递方法C+代码优化,什么是混合编程,多种程序设计语言间,通过相互调用、参数传递、共享数据结构和数据信息而形成程序的过程就是混合编程程序的大部分采用高级语言编写,以提高程序的开发效率;在某些部分,利用汇编语言编写,以提高程序的运行效率,混合编程方法,嵌入式汇编在C/C+语言中直接使用汇编语言语句,简洁直观、功能较弱模块连接两种语言分别编写独立的程序模块,分别产生目标代码OBJ文件,然后进行连接,形成一个完整的程序使用灵活、功能强,要解决参数传递问题,混合编程的关键问题,建立不同语言之间的接口在不同格式的两种语言间提供有效的通讯方式,作出符合两种语言调用约定的某种形式说明,实现两种语言间的程序模块互相调用、变量的相互传送以及参数和返回值的正确使用,7.1 Turbo C嵌入式汇编方式,格式asm 操作码 操作数 举例asm mov ax,ds;asm pop ax;asm pop ds;asm ret;asm push ds/*asm语句是C程序中唯一可以用换行结尾的语句*/,7,若干注意事项,操作码支持8086/8087指令或若干伪指令:db/dw/ddextern 操作数是操作码可接受的数据:立即数、寄存器名,还可以是C语言程序中的常量、变量和标号等内嵌的汇编语句可以用分号“;”结束,也可以用换行符结束 使用C的注释,如/*/正确运用通用寄存器、标号等,8,访问C语言的数据,嵌入的汇编语句除可以使用指令允许的立即数、寄存器名外,还可以使用C语言程序中的任何符号(标识符),包括变量、常量、标号、函数名、寄存器变量、函数参数等;C编译程序自动将它们转换成相应汇编语言指令的操作数,并在标识符名前加下划线。对于具有内嵌汇编语句的C程序,C编译器要调用汇编程序进行汇编。汇编程序在分析一条嵌入式汇编指令的操作数时,若遇到了一个标识符,它将在C程序的符号表中搜索该标识符;但8086寄存器名不在搜索范围之内,而且大小写形式的寄存器名都可以使用。,9,访问C语言的数据,例7.1:用嵌入汇编方式实现取两数较小值的函数min/*LT701.C*/int min(int var1,int var2)/*用嵌入汇编语句实现的求较小值*/asm mov ax,var1 asm cmp ax,var2 asm jle minexit asm mov ax,var2minexit:return(_AX);/*将寄存器AX的内容作为函数的返回值*/main()/*C语言主程序*/min(100,200);,注意事项,10,嵌入汇编的编译过程,C语言程序中含有嵌入式汇编语言语句时C编译器首先将C代码的源程序(.c)编译成汇编语言源文件(.asm)然后激活汇编程序Turbo Assembler将产生的汇编语言源文件编译成目标文件(.obj)最后激活Tlink将目标文件链接成可执行文件(.exe)。,/*LT702.C*/#include void upper(char*dest,char*src)asm mov si,src/*dest和src是地址指针*/asm mov di,destasm cldloop:asm lodsb/*C语言定义的标号*/asm cmp al,aasm jb copy/*转移到C的标号*/asm cmp al,zasm ja copy/*不是a到z之间的字符原样复制*/,例7.21/2,asm sub al,20h/*小写字母转换成大写*/copy:asm stosbasm and al,al/*C语言中,字符串用NULL(0)结尾*/asm jnz loopmain()/*主程序*/char str=This Started Out As Lowercase!;char chr100;upper(chr,str);printf(Origin string:n%sn,str);printf(Uppercase String:n%sn,chr);,例7.22/2,DEMO例7.2,13,7.2 Turbo C模块连接方式,要注意模块连接的约定规则命名约定:汇编语言过程应采用C语言类型 声明约定寄存器使用约定存储模式约定:采用相同的存储模式参数传递是关键通过堆栈传递入口参数通过寄存器返回出口参数,7.2.1 混合编程的约定规则,;汇编语言子程序:lt703s.asm.model small,c;小型存储模式.datamsgdb Hello,C and Assembly!$.codePUBLIC displaydisplayprocmov ah,9;小型模式不必设置DSmov dx,offset msg;寄存器AX和DX无须保护int 21hretdisplayendpend,例7.31/2,7.2.2 编译和连接过程,/*C语言程序:lt703.c*/extern void display(void);/*说明display是外部函数*/main()display();,利用汇编程序编译汇编语言程序成目标代码文件:ML/c lt703s.asm 或 masm lt703s.asm利用C编译程序编译C程序、连接目标代码文件:TCC-c lt703.c,例7.32/2,DEMO,16,编译和连接过程,利用连接程序将各个目标代码文件连接在一起,得到可执行程序文件,例如:TLINK libc0s lt703 lt703s,lt703.exe,libcs注意:直接使用Turbo C的连接程序TLINK进行连接时,用户必须指定要连接的与存储模式一致的初始化模块和函数库文件,并且初始化模块必须是第一个文件。编译和连接也可以利用命令行一次完成,一般格式为:TCC-mx-I包含文件路径-L库文件路径 filename1 filename2.例如,上例可以利用如下命令:TCC-ms-Iinclude-Llib lt703.c lt703s.obj,17,7.2.3 混合编程的参数传递,Lt0701.c 的编译结果如教材P218 mov ax,200 push ax;压入参数200(第2个参数)mov ax,100 push ax;压入参数100(第1个参数)call near ptr _min;调用min(100,200)pop cx;两条出栈指令用于平衡堆栈 pop cx,;汇编语言子程序:lt704s.asm.model small,cPUBLIC min.codeminproc;小型模式,为近过程push bpmov bp,spmov ax,bp+4;取第1个参数cmp ax,bp+6;与第2个参数比较jle minexitmov ax,bp+6;保存返回值minexit:pop bpretminendpend,例7.41/3,图示,;汇编语言子程序:lt704.asm.model small,cPUBLIC min.codeminproc,var1:word,var2:wordmov ax,var1;取第1个参数cmp ax,var2;与第2个参数比较jle minexitmov ax,var2;保存返回值minexit:pop bpretminendpend,例7.42/3,/*C语言程序:lt704.c*/extern int min(int,int);main()printf(“%d”,min(100,200);,小型模式编译程序和连接:TCC-ms-Iinclude-Llib lt704.c lt704s.obj大型模式编译程序和连接:TCC-ml-Iinclude-Llib lt704.c lt704l.obj,例7.43/3,例7.4的堆栈区,小型模式,大型模式,7.3 汇编语言在Visual C+中的应用,Visual C+逐渐将MASM融合进去嵌入汇编语言指令调用汇编语言过程Visual C+集成开发环境编译汇编语言程序调试汇编语言程序应用之一:优化C+代码,7.3.1 嵌入汇编语言指令,格式_ _asm 指令 举例int power2(int num,int power)_ _asmmov eax,nummov ecx,powershl eax,cl/返回 EAX=EAX(2CL),7.3.2 调用汇编语言过程,必须遵循共同的约定规则命名约定声明约定寄存器使用约定存储模式约定参数传递约定采用一致的调用规范声明共用函数和变量正确传递入口参数和返回参数,32位汇编语言过程,用.386p等处理器伪指令说明采用的指令集32位逻辑段环境有些指令在32位段与16位段有差别采用平展模式(flat)汇编时采用选项/coff,;汇编语言子程序:lt714f.asm.386p.model flat,cPUBLIC power2.codepower2procpush ebpmov ebp,espmov eax,ebp+8;取第1个参数mov ecx,bp+12;取第2个参数shl eax,clpop ebpret;返回EAXpower2endpend,例7.141/3,图示,例7.14的堆栈区,;汇编语言子程序:lt714f.asm.386p.model flat,cPUBLIC power2.codepower2PROC,num:dword,power:dwordmov eax,num;获取参数mov ecx,powershl eax,cl;计算ret;EAX存放返回值power2ENDPend,例7.142/3,/C+语言程序:lt714.cpp#include extern“c”int power2(int,int);void main(void)cout“2的6次方乘5等于:t”;coutpower2(5,6)endl;,将汇编语言程序汇编成目标代码文件:ML/c/coff lt714f.asm在Visual C+6.0编译环境下创建项目,插入汇编成的目标代码文,然后编译连接,例7.143/3,/C+程序:LT715.CPP#include extern C long isum(int,int*);int imin(int,int*);void main(void)const int SIZE=10;int arraySIZE;int temp;coutarraytemp;coutendl;cout整数数据之和:tisum(SIZE,array)endl;cout其中最小值为:timin(SIZE,array)endl;,例7.151/4,/求itmp个元素的数组iarray的最小数int imin(int itmp,int iarray)_asm mov ecx,itmpjecxz minexit;个数为0,返回dec ecxmov esi,iarraymov eax,esijecxz minexit;个数为1,返回minlp:add esi,4cmp eax,esi;比较两个数据的大小jle nochangemov eax,esi;取得较小值nochange:loop minlpminexit:,例7.152/4,;汇编语言子程序:LT715F.ASM.386p.model flat,c.code;32位有符号数据的求和过程isumproc uses ecx esi,count:dword,darray:PTRmov ecx,count;个数为0,和为0 xor edx,edxxor eax,eaxjecxz sumexitmov esi,darray;个数为1,和为本身mov eax,esidec ecxjecxz sumexit,例7.153/4,sumlp:add esi,4add eax,esi;计算低32位adc edx,0;计算高32位loop sumlpsumexit:retisumendpend,例7.154/4,将汇编语言程序汇编成目标代码文件:ML/c/coff lt715f.asm在Visual C+6.0编译环境下创建项目,插入汇编成的目标代码文件,然后编译连接,34,7.3.3 使用汇编语言优化C+代码,例7.16:在整数数组查找一个数值,查找过程需要进行大量循环C+代码(lt716.cpp)Debug调试版本:81000(0.046 ms)Release发布版本:31000(0.018 ms)嵌入汇编语言编写查找函数使用串操作指令:41000(0.023 ms)不使用串操作指令:31000(0.018 ms)在简单情况下,Visual C+的优化技术已经非常有效;但仍然可用汇编代码进行改进,35,7.3.4 使用Visual C+开发汇编语言程序,新建工程项目,选择32位控制台或窗口应用程序输入磁盘目录,工程名称,并选择创建一个空白工程新建汇编语言源程序文件输入源程序文件名以及扩展名ASM,加入工程项目通过工程菜单的设置命令展开工程设置窗口在命令文本框中输入进行汇编的命令在输出文本框输入汇编后目标模块文件名调用创建命令进行汇编语言程序的汇编和连接注意在Visual C+环境确定包含文件的路径,36,汇编语言程序的调试过程,工具菜单的选项命令展开调试标签页进行设置通用下选中十六进制显示反汇编窗口下要选中代码字节存储器窗口下选中固定宽度,后面填入数字16在编辑窗口源程序的语句行,按F9键,设置断点使用运行、单步执行等命令进行开各种窗口观察程序当前的运行状态存储器窗口查看变量反汇编窗口有反汇编的实际执行代码寄存器窗口显示处理器的寄存器内容,37,第7章 教学要求,熟悉嵌入式和模块连接两种混合编程方法了解模块连接混合编程的约定规则熟悉模块链接混合编程的参数传递方法了解32位环境的混合编程方法,