第8章 语言与高级语言的连接(教案)_大班幼小衔接语言教案

教案模板 时间:2020-02-29 05:03:33 收藏本文下载本文
【www.daodoc.com - 教案模板】

第8章 语言与高级语言的连接(教案)由刀豆文库小编整理,希望给你工作、学习、生活带来方便,猜你可能喜欢“大班幼小衔接语言教案”。

13.3汇编语言和高级语言程序的连接

由于使用高级语言编写及调试程序比汇编语言的开发效率高,可移植性好,所以,高级语言比汇编语言使用更广泛。但是在要求实时性高、占用空间少或要求直接控制硬件的场合,仍然要用到汇编语言,实现对硬件直接控制和更快的控制速度。但汇编语言编程复杂、表达能力也差,因此比较好的解决办法是C语言与汇编语言混合编程。

目前主要的C语言程序开发环境有:Turbo C/C++、Borland C/C++,Visual C++等,都支持与汇编语言的混合编程。C语言与汇编语言的混合编程方法一般有两种方法可以实现,即在C语言中嵌入汇编语言,也称嵌入式编程和用 C语言调用汇编语言模块,即多模块混合编程。

1.汇编语言的嵌入式编程

1.内嵌汇编语句格式

在Turbo C中,C程序中嵌入的汇编语句前必须以关键字ASM开头,其格式为:

ASM /*注释*/ 其中ASM为关键字,操作码可以是处理器指令也可以是伪指令,操作数是操作码可以接受的数据,可以是指令允许的立即数,寄存器名,也可以是C程序中的常量、变量和标号。C程序中嵌入汇编代码后可以有分号也可无分号,如果汇编代码后无分号则必须以换行符结束(嵌入的汇编语句是C语言中唯一可以换行结束的语句),如果汇编代码后有分号,则一行中可以有多条嵌入的汇编语句,但一条汇编指令不能跨越两行。

特别要注意的是,嵌入的汇编语句的注释方式须采用C语言的注释方式,即必须用/*……*/来标记注释。而不能像纯汇编那样用(;)作为一条注释的开始。如:

ASM MOV AX,DX;

/*单个语句*/ ASM PUSH AX;ASM POP AX;ASM MOV BX, AX;/*多个语句写在一行 */ 如果在C语言程序中要嵌入多个ASM语句,可以将它们放在花括号内。如: ASM {

MOV AX,DX

PUSH AX

}/*注释*/

在C程序中,函数内部的汇编语句都是一条可执行的语句,它被编进程序的代码段,在函数外部的汇编语句是一个外部说明,在编译时放在程序的数据段中。这些外部数据可以被其他程序引用。C语言允许嵌入的指令集是有限的,它跟C语言的编译环境有关。在Turbo C2.0中允许嵌入的汇编指令主要包括8086指令集,例如一般传送和运算指令、串操作指令、跳转指令、数据分配和定义指令等。

嵌入汇编比调用汇编子程序更方便、灵活、功能也更强。但嵌入汇编不是一个完整的汇编程序,所以许多错误不能马上检查出来。2.转移指令的执行

内嵌汇编指令可以使用转移指令和LOOP循环指令,但是它们只能在函数体内有效,不允许进行段间转移。由于ASM语句中不能给出标号,因而转移指令只能使用C语言程序中GOTO语句使用的标号。例如:

int fun1(){ … label: … asm … } jmp label 3.直接嵌入汇编代码的C语言程序示例

例 编写一个三个整数的求和的C函数,用在C语言中嵌入汇编语言方法实现。

int Sum(int X, int Y, int Z)

{ ASM PUSH AX;/*保护现场,否则可能影响前面的程序执行*/ ASM MOV AX, X;ASM ADD AX, Y;ASM ADD AX, Z;ASM MOV X , AX;ASM POP

AX;

/*恢复现场*/ return(X);

}

例.用嵌入汇编的方法编写实现求两个整数中的最小值的C语言函数。

int min(int v1,int v2){ ASM MOV AX,v1 ASM CMP AX,v2 ASM JLE over;ASM MOV AX,v2 over: return(_AX);/*_AX为AX寄存器*/ } 内嵌汇编指令的C程序只能采用TCC命令行的编译连接方法。用TCC命令行实现的编译连接的方法是:

TCC-B-L: LIB 文件名 库文件名

其中-L选择项指定了连接所需的库文件路径,文件名指有内嵌汇编指令的C程序名,库文件指程序重要用到的库函数所在的库文件(Turbo C标准库可省略)。

内嵌汇编指令的C程序进行编译时,必须要有-B选择项,否则编译时,一旦遇到汇编代码,便立即给出警告信息,并以-B选项重新进行编译,若在C程序中加上#program inline预处理语句,则可省略-B选择项。

2.在C程序中直接调用汇编子程序

在C语言中直接嵌入汇编语句的方法限制较多,不能充分发挥汇编语言的功能。一种更好的方法是把需要用汇编实现的工作设计成汇编子程序,然后由C语言调用。

在设计能被C调用的汇编子程序时,可以使用完整的段定义或者简化的段定义结构。2.1编写汇编子程序注意的问题

(1)变量和函数的使用

(2)参数传递(3)寄存器使用规则(4).存储模式规则

(1)变量和函数的使用

C程序中可以调用汇编子程序及定义的变量,汇编子程序也可以调用C语言书写的函数和定义的变量。但是,C语言编译系统在编译C语言源程序时,要在其中的变量名、过程名、函数名等标识符前面加下划线“_”。例如,在C语言程序中变量name,在编译以后变量变为_name。依次在汇编语言中调用C语言的函数和变量时,应在函数名和变量名前面加上下划线“_”。并在汇编语言程序的开始部分,应对调用的函数和变量用EXTERN加以说明。

其格式为:

EXTERN_函数名:函数类型 EXTERN_函数名:变量类型

其中,函数类型指明该函数是一个近程或远程函数(NEAR或FAR),变量类型为变量的数据类型。

其对应关系:

C语言

汇编语言

数据长度(字节)Char

DB(BYTE)int short

DW(WORD)long

DD(DWORD)float double

DQ(QWORD)例如调用C程序中名为myfunc()的函数和变量mem等,则在C语言程序中说明为:

int myfunc(vido);int mem;char ch;long result 在调用它的汇编子程序中说明为: exteern _ myfunc:char extrn_mem:word,ch:byte,result:dword 若C程序调用汇编语言中的子程序或变量,则在汇编语言中用public进行说明,且函数名和变量名前用下划线。如::

public _myfunc01 public_num 而在C语言中则应将其说明为extern,即: extern myfunc01();extern num;要注意此处不能带有下划线,同时要注意C语言对大小写敏感的问题。(2)参数传递

C语言调用汇编子程序时,参数是通过堆栈传递给汇编子程序的,要注意C语言程序参数入栈的的顺序是从右到左,在执行汇编子程序前还要将返回地址压入堆栈。由于堆栈是向下生长的,故每入栈一次。栈指针都相应减少;而在出栈时相反。

例如,在C程序中说明一个用汇编书写的函数,若在小内存模式下编译,则表示为:

void abc(char*p1,int p2);在大内存模式下编译,则要说明为远程的,如下所示:

void far abc(char*p1,int p2);在大内存模式下,要将相应的段地址和便移地址入栈。3.寄存器使用规则

在C语言中调用的汇编语言模块中,通常汇编程序可以任意使用计算机内部的通用寄存器,如AX、BX、CX、DX、ES等。这些通用寄存器的值在调用后可以发生改变,标志寄存器的值也可以发生改变。但有些寄存器如:DS、CS、SS、BP、SP等,如果在调用的汇编语言程序中有用到,则必须先进行保护(入栈),退出前加以恢复(出栈)。变址寄存器SI和DI如在调用汇编语言程序中使用到也要加以保护。

4.存储模式规则 在TURBO C中提供了6种不同的存储模式,分别对应6种不同的汇编语言存储模式。即对不同的C语言存储模式(极小、小、紧凑、中、大和巨)要选用相应的汇编语言存储模式,如C程序为小模式,汇编程序也用小模式,C程序为大模式,汇编也用大模式等。

设定汇编语言的存储模式可采用.MODEL伪指令,设定TUBRO C的存储模式可利用TCC命令行的选项-m。

下面是一个C语言程序调用汇编语言子程序的例子,假定C语言主程序存放在文件c_main.c和masm_sub.asm中,其内容分别如下:

c_main.c文件: extern int divs(int,int);/*声明divs为外部函数*/ main(){

printf(“%d\n”,divs(16,3));/*调用外部函数*/ }

masm_sub.asm文件

.MODEL SMALL

;采用小模式.CODE

PUBLIC divs

;指明该过程可被外部调用 divs proc PUSH BP

;保护bp MOV BP,SP MOV AX,[BP+4]

;参数 MOV CX,[BP+6]

;另一个参数 SHR AX,CL

POP BP

;恢复bp RET divs ENDP END 其中伪指令model small 对应C的小模式编译;code 标志一个代码段的开始,这是MASM 5.0的简化段格式;puplic divs 说明divs是公用的,可以由外部其它单独编译模块调用。

将C源程序以文件名c_main.c存盘,汇编语言源程序以文件名masm_sub.asm 存盘;再分别用各自的编译系统,编译成目标程序c_main.obj和masm_sub.obj;最后用link连接程序,将两个目标程序连 接成可执行程序c_main.exe。

其实,汇编语言与C语言混合编程时,除了可以在C语言中调用汇编语言子程序,也可以在汇编语言代码中调用C语言函数,但在调用时要注意函数参数的传递方法。详情请参见有关文献资料。

3.使用C和汇编语言混合编程的编译及连接

对于用C语言和汇编语言分别独立编写的符合以上要求的程序,要想使它们最终形成一个系统,需要对他们进行编译和连接,以便生成一个可执行文件。

在混合编程时要注意,C程序和汇编语言子程序所采用的内存模式,当都是小/微/紧凑模式时,在C程序的说明部分是需要说明为EXTERN即可,否则必须说明为FAR型,下面是在Turbo C环境下同为小内存模式的混合编程的例子。

例 : 从6个数中找出其中的最大数并显示。要求查找最大数的功能由汇编语言子程序max-num实现。

(1)编写源程序

汇编子程序使用简化的段格式编写。C程序调用该子程序时,共传递7个参数,第一个为数据的个数,其余为数据部分。

源程序如下:

#include /*program name :c_max.c*/ int extern max_num(int count,int v1,int v2,int v3,int v4,int v5,int v6);main(){ int i;i=max_num(6,-35,17,0,63.121,112);printf(“n the maximum of the 6 numbers %d,i);} 对应的汇编程序如下:

.model small

;program name :asm_max.asm

.code

public _max_num _max_num proc near

push bp

mov bp,sp

mov cx,[bp+4]

;取数据个数

jcxz exit

mov ax,[bp+6]

;取第一个数据 comp: add bp,2

;修改地址指针

cmp ax,[bp+6]

;两数比较

jge gtest

mov ax,[bp+6]

;大数放在AX中 gtest: loop comp exit:

pop bp

ret _max_num endp

end

(2)编译和连接

①在DOS环境下,用TASM或MASM将汇编语言子程序(asm_max_asm)编译生成目标文件.obj(asm_max.obj)。例如:tasm asm_max.②在TC主界面下,单击主菜单中的project项,选中子项project name,输入一个后缀为为.prj的工程文件(例如max.prj)该文件包含需要编译连接的C语言源程序和它调用的汇编语言子程序的目标文件名,对于本例,其内容为:

c_max.c asm_max.obj ③关闭大小写敏感开关,即把Options选项的Linker的Case-sensitive Link置成OFF。

④按F9键对工程文件进行编译连接,生成一个.exe文件,本例为max.exe.⑤在DOS环境下输入MAX运行该可执行程序。

对于不是小/微/紧凑内存模式下的混合编程,C程序必须把被调用的汇编子程序说明为远程函数,若有函数参数为指针类型时,也要说明成FAR型,即它包含段地址和便移地址两部分。

例:求若干个16位带符号数之和,其和为32位数。

要求求和程序用汇编语言编写,而定义数据和及显示用C语言编写。

参考程序如下:

extern long asum(int*,int);int buf[5]=10000,-20000,30000,6000,0);main(){ long x;x=asum(buf,5);printf(“x=%dn”,x)}

子程序—汇编源程序 fram struc regbp dw ? retaddr dw ? pointer dw ? count dw ? farm ends.model small.code public _asm;声明为公用子程序

_asm proc push bp mov bp,sp push si push di cld mov si,[bp].pointer mov cx,[bp].count xor bx,bx mov di,bx c1:lodsw cwd add bx,ax adc di,dx loop c1 mov dx,di;返回结果的高16位 mov ax,bx ;返回结果的低16位 pop di pop si pop bp ret _asum endp end 在C函数中声明asum是外部函数,并定义了若干个数组元素,然后调用汇编子程序asum求和,最后把结果显示在屏幕上。

在汇编程序中首先声明asum子程序是公用的,然后使用由堆栈传递的数组开始地址及元素个数,从数组中取出元素求和,返回的32位结果在DX:AX中。;求数组和

4. 汇编语言程序调用C函数

如同C语言程序调用汇编语言子程序一样,在汇编语言中调用C函数时也要按有关约定编程。

(1)在汇编语言中,对所使用的C函数和变量名在其名字前均应加下划线。例如,调用一个C函数func(),则在汇编程序中应写作call_func.(2)对调用的C函数用EXTERN伪指令加以说明。若函数为NEAR型,EXTERN语句可以放在代码段中,为FAR型,则要放在所有的段之外。

(3)对汇编语句中使用的C函数变量用“EXTERN变量名:size”说明,其中,SIZE视数据类型而定。例如int 型为2。

(4)参数传递有两种,一种是在C程序中定义变量,在汇编程序中把它说明成EXTERN型,另一种是采用堆栈传递,这时要注意压入堆栈的顺序。

MASM6.0汇编语言程序上机

汇编语言程序上机过程分为编辑、汇编、连接和调试4个步骤。

(1)编辑源程序

编辑源程序是利用文本编辑工具生成一个由汇编语言语句构成的文本文件,文件扩展名为.ASM,扩展名不能省略。

(2)汇编源程序

汇编语言源程序不能直接执行,必须转换为机器语言程序,这个过程叫汇编。最常用的汇编工具为MASM软件,它有很多版本,这里主要介绍MASM6.X。MASM6.X包含了许多文件,最常用的文件有:

ML.EXE

LINK.EXE CV.EXE 汇编程序 连接程序

调试程序Code View 1.汇编程序ML.EXE(Masm and Link)

ML可以自动调用LINK,实现对程序的汇编和连接。设源文件名为MYFILE.ASM,汇编的基本命令格式为:

ML/c MYFILE.ASM 其中,源文件的扩展名为.ASM。若程序无语法错误,则汇编后将生成MYFILE.OBJ文件。此外若不带参数/c,直接使用命令;

ML MYFILE.ASM 则ML将自动调用连接程序LINK进行连接,生成MYFILE.OBJ与MYFILE.EXE,这样就不需要单独使用LINK命令。

ML包含很多命令参数,使用命令/?可以列出ML允许的所有参数及其说明。ML命令格式如下:

ML[/〈选项〉]〈源文件列表〉[/LINK〈连接选项〉] 其中,方括号中的内容为可选项。ML后的参数是大小写敏感的。“/〈选项〉”是可选的一个或多个参数,每个参数均以“/”开头,参数之间以空格分开。〈源文件列表〉中多个文件以空格分开,要求给出完整的文件名。

ML允许的选项很多,常用的选项如下: /AT /c

生成.COM文件 只汇编,不连接

指定生成的可执行文件名 /Fe〈可执行文件名〉

/F1〈列表文件名〉 同名

/Fm〈映像文件名〉 文件同名

/Fo〈目标文件名〉 /I〈包含路径名〉

产生列表文件(.LST),缺省与源文件

产生映像文件(.MAP),缺省与源

指定生成的目标文件名 指定include文件的路径名

ML除了产生目标文件外,还可以根据需要生成一些其它文件,如列表文件(.LST)和映像文件(.MAP)。例如,下列命令

ML/F1/Fm myfile.asm 除了能生成myfile.obj与myfile.exe外,还能生成列表文件myfile.lst与映像文件myfile.map。2.列表文件

列表文件是一个文本文件,其内容包括两部分。第一部分中从左到右依次列出数据或指令在段内的偏移地址,机器代码和源程序。若程序中有语法错误,则列出错误信息。第二部分列出了程序中定义的所有标识符的信息,比如段的名称、大小与长度,变量与标号的名称、类型与偏移地址等。3.映像文件

映像文件是一个文本文件,主要列出每个段的内存分配,给出了每个段的起点、终点、长度、段名、类别以及程序执行的起始地址等。

4.8.3目标程序的运行和调试

经过汇编、连接后产生的.EXE可执行文件可在DOS状态下直接输入文件名运行该程序。

如果出现错误,可用动态调试程序DEBUG进行调试,找出错误后,再重复上述过程,直到程序正确为止。调试的方法包括单步执行、设置断点、连续执行、修改内存单元以及寄存器的值。本章小结

不论是汇编语言还是高级语言,程序设计的过程大致是相同的。一般都要经过问题分析、算法确定、框图表达、源程序编写等步骤。编写汇编语言程序要严格遵循汇编语言程序的基本语法格式。伪指令是辅助汇编的命令,合理使用汇编语言的伪指令可以使程序简化,可读性强、执行速度快;简化的段定义伪指令使用指定的存储模式编程,给程序设计带来极大的方便;使用MASM6.X中的过程调用伪指令调用过程,极大地方便了过程或参数间的传递。宏可以把重复出现的一段程序定义为一条宏指令,这样,在源程序中就可以用一条宏指令代替所定义的程序段,在汇编时遇到宏指令,汇编程序就将其替换成相应的代码块。C语言与汇编语言混合编程较好地解决了微机对硬件直接控制和提供更快的控制速度问题。熟练掌握汇编语言的编程技术,掌握顺序、分支、循环和子程序的编程方法、掌握DOS系统功能调用和汇编语言与C语言的混合编程方法,才可以编写高质量的程序。

习题

求若干个16位带符号数之和,其和为32位数。

(要求求和程序用汇编语言编写,而定义数据及显示用C语言编写)。

主程序—C Extern

long

asum(int*,int);

{

} Int buf[5]={10000,-20000,30000,6000,0};Main()

long x;x=asum(buf,5);printf(“x=%dn”,x)子程序—汇编程序 PRAM REGBP STRUC DW ? ? ? ? RETADDR DW POINTER COUNT PRAM

DW DW ENDS.MODEL SMALL.CODE

;申明为公用子程序 PUBLIC _asum _asum PROC PUSH BP

C1:

_asum MOV BP,SP PUSH SI PUSH DI CLD MOV SI, [BP].POINTER MOV CX,[BP].COUNT XOR BX,BX MOV DI,BX LODSW

;求数组和

CWD ADD BX,AX ADC DI,DX LOOP C1 MOV DX,DI ;返回结果的高16位MOV AX,BX ;返回结果的低16位POP DI POP SI POP BP RET ENDP

END 在C函数中申明asum是外部函数,并定义了若干个 数组元素,然后调用汇编子程序求和,最后半结果显示在屏幕上。

通过该例应学会C的数组指针与汇编语言程序中数组首地址的对应关系。

习题

P258

8.1 , 8.4,8.5

下载第8章 语言与高级语言的连接(教案)word格式文档
下载第8章 语言与高级语言的连接(教案).doc
将本文档下载到自己电脑,方便修改和收藏。
点此处下载文档

文档为doc格式

    热门文章
      整站推荐
        点击下载本文