汇编与C的混合编程

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

.CODE Move PROC NEAR32 c uses eax ebx, countp:word, Sr:byte , Dst:byte, Spa: byte cmp countp , 1 ; NbrDisks = 1? jne elseMore ; skip if more than 1 mov bx,word ptr Sr ; Source mov source,bl ; copy character to output mov bx,word ptr Dst ; destination mov dest,bl ; copy character to output output message ; print line jmp endIfOne ; return elseMore: dec countp INVOKE Move, countp, Sr, Spa, Dst INVOKE Move, 1, Sr, Dst, Spa INVOKE Move, countp, Spa, Dst, Sr endIfOne: ret ; return Move ENDP
若干注意事项
操作码支持8086/8087指令或若干伪指令:db/dw/dd和extern 操作数是操作码可接受的数据:立即数、寄存器名,还可以是C语言程序中的常量、变量和标号等 内嵌的汇编语句可以用分号“;”结束,也可以用换行符结束 使用C的注释,如 / * … * / 正确运用通用寄存器、标号等
start: output prompt ; ask for number of disks input number,16 ; read ASCII characters atoi number ; convert to integer INVOKE Move, ax, 'A', 'B', 'C' INVOKE ExitProcess, 0 ; exit with return code 0 PUBLIC start ; make entry point public END ; end of source code
从右到左
Hale Waihona Puke 从右到左 (注) 从左到右
从左到右
从左到右
平衡堆栈的程序
调用程序
被调用程序
被调用程序
被调用程序
被调用程序
被调用程序
保存BP



允许VARARG参数



作用范围
作用范围——可以是PUBLIC、PRIVATE、EXPORT,表示该过程是否对其他模块可见。缺省是PUBLIC,表示其他模块可见;PRIVATE表示对外不可见;EXPORT隐含有PUBLIC和FAR,表示该过程应该放置在导出表(export entry table)。
例7.2-1/2
asm sub al,20h /*小写字母转换成大写*/ copy: asm stosb asm and al,al /* C语言中,字符串用NULL(0)结尾 */ asm jnz loop } main() /* 主程序 */ { char str[]="This Started Out As Lowercase!"; char chr[100]; upper(chr,str); printf("Origin string:\n%s\n",str); printf("Uppercase String:\n%s\n",chr); }
列表文件
什么是混合编程
多种程序设计语言间,通过相互调用、参数传递、共享数据结构和数据信息而形成程序的过程就是混合编程 程序的大部分采用高级语言编写,以提高程序的开发效率;在某些部分,利用汇编语言编写,以提高程序的运行效率
混合编程方法
嵌入式汇编—— 在C/C++语言中直接使用汇编语言语句, 简洁直观、功能较弱 模块连接—— 两种语言分别编写独立的程序模块,分别产生目标代码OBJ文件,然后进行连接,形成一个完整的程序 使用灵活、功能强,要解决参数传递问题
参数
参数∶类型——表示过程使用的形参及类型。在16位段中,缺省的类型是字WORD,在32位段中缺省的类型是双字DWORD。 参数类型可以是任何MASM有效的类型或PTR(表示地址指针);在C、SYSCALL、STDCALL语言类型中。 PROC伪指令中使用参数,必须定义语言类型。
局部变量
如果过程使用局部变量,紧接着过程定义伪指令PROC,可以采用一条或多条LOCAL伪指令说明。 其中,可选的“[个数]”表示同样类型数据的个数,类似数组元素的个数。在16位段中,缺省的类型是字WORD,在32位段中缺省的类型是双字DWORD。使用LOCAL伪指令说明局部变量后,汇编系统将自动利用堆栈存放该变量.
例7.2-2/2
Turbo C模块连接的约定规则
命名约定 汇编语言过程应采用C语言类型 声明约定 C对调用的外部过程、变量等采用EXTERN说明 汇编语言程序的标识符用public操作符定义 寄存器使用约定 存储模式约定 采用相同的存储模式 参数传递约定:堆栈和共享变量
; 汇编语言子程序:lt703s.asm .model small,c ;采用小型存储模式 .data msg db ’Hello, C and Assembly ! $’ .code PUBLIC display display proc ;过程名加有下划线 mov ah,9 ;小型模式不必设置DS mov dx,offset msg ;寄存器AX和DX无须保护 int 21h ret display endp end
/ * LT702.C */ #include <stdio.h> void upper(char *dest,char *src) { asm mov si,src /* dest和src是地址指针 */ asm mov di,dest asm cld loop: asm lodsb /* C语言定义的标号 */ asm cmp al,'a' asm jb copy /* 转移到C的标号 */ asm cmp al,'z' asm ja copy /* 不是’a’到’z’之间的字符原样复制 */
混合编程的关键问题
建立不同语言之间的接口 在不同格式的两种语言间提供有效的通讯方式,作出符合两种语言调用约定的某种形式说明,实现两种语言间的程序模块互相调用、变量的相互传送以及参数和返回值的正确使用
Turbo C嵌入式汇编方式
格式 asm 操作码 操作数 <;或换行> 举例 asm mov ax,ds; asm pop ax; asm pop ds; asm ret; asm push ds
例fig6-20new.asm
此例该自fig6-20.asm,请注意比较。
.386 .MODEL FLAT, stdcall ExitProcess PROTO NEAR32 stdcall, dwExitCode:DWORD Move PROTO NEAR32 C, :WORD, :BYTE, :BYTE, :BYTE include io.h ; header file for input/output cr equ 0dh ; carriage return character Lf equ 0ah ; line feed
汇编与C/C++的混合编程
要调用带参数过程定义的过程,不应采用CALL指令,因为比较烦琐 应该采用过程调用伪指令INVOKE 使用INVOKE伪指令的前提是需要用PROTO伪指令对过程进行声明
过程声明和过程调用伪指令
过程名 PROC 调用距离 语言类型 作用范围 <起始参数> USES 寄存器列表, 参数:类型 LOCAL 参数表 … ;汇编语言语句 过程名 ENDP
语言类型
语言类型——可以是任何有效的语言类型,确定该过程采用的命名约定和调用约定;语言类型还可以由.model伪指令指定
语言类型
C
SYSCALL
STDCALL
PASCAL
BASIC
FORTRAN
命名约定
名字前加下划线
名字前加下划线
名字变大写
名字大写
名字大写
参数传递顺序
例7.3-1/2
/* C语言程序:lt703.c */ extern void display(void); /* 说明display是外部函数 */ main() { display(); }
利用汇编程序编译汇编语言程序成目标代码文件: ML /c lt703s.asm 利用C编译程序编译C程序、连接目标代码文件: TCC -ms -Iinclude -Llib lt703.c lt703s.obj
起始参数
起始参数——采用这个格式的PROC伪指令,汇编系统将自动创建过程的起始代码(Prologue code)和收尾代码(Epilogue code),用于传递堆栈参数以及清除堆栈等。起始参数表示传送给起始代码的参数;它必须使用尖括号“< >”括起来,多个参数用逗号分隔。
寄存器列表
寄存器列表——指通用寄存器名,用空格分隔多个寄存器。只要利用“USES 寄存器列表”罗列该过程中需要保存与恢复的寄存器,汇编系统将自动在起始代码产生相应的入栈指令,并对应在收尾代码产生出栈指令。
例7.3-2/2
; 汇编语言子程序:lt704s.asm .model small,c PUBLIC min .code min proc ;小型模式,为近过程 push bp mov bp,sp mov ax,[bp+4] ;取第1个参数 cmp ax,[bp+6] ;与第2个参数比较 jle minexit mov ax,[bp+6] ;保存返回值 minexit: pop bp ret min endp end
.STACK 4096 ; reserve 4096-byte stack .DATA ; reserve storage for data prompt BYTE cr,Lf,'How many disks? ',0 number BYTE 16 DUP (?) count word ? message BYTE cr,Lf,'Move disk from spindle ' source BYTE ? BYTE ' to spindle ' dest BYTE ? BYTE '.',0
过程声明伪指令:用于事先声明过程的结构 过程名 PROTO 调用距离 语言类型, 参数:类型 过程调用伪指令 INVOKE 过程名,参数,...
如何调用
调用距离
调用距离——可以是NEAR16、NEAR32、FAR,表示该过程是近或远调用。简化段格式中,缺省值由.model语句选择的存储模式决定。
相关文档
最新文档