您的位置: 网站首页 > 程序开发 > 汇编语言与微机原理教程 > 第11章 模块化程序设计 > 【11.4 C++语言与汇编语言混合编程】

11.4 C++语言与汇编语言混合编程

 

11.4  C++语言与汇编语言混合编程

现在,用汇编语言开发整个系统已经很少见了,通常我们用汇编语言和C++语言一起进行开发。汇编语言通常完成C++语言难以实现或实现效率不能满足要求的任务。本节将详细介绍汇编语言和C++语言混合编程的思想。

11.4.1  C++程序中使用汇编语言

汇编与C++混合编程的一种较为简单的方法是在C++程序中内嵌汇编语句(内嵌的汇编器不支持宏指令和部分伪指令)。在C++语言中嵌入汇编语言的语法如下:

_ASM<汇编指令><;汇编指令>……

注意:这里的分号不是汇编语言中起注释作用的分号,而是作为语句的分隔符。

若要在C++语言源程序中嵌入一条汇编语句,则可按下列方式操作:

_ASM MOV AX,data

若要嵌入一组汇编语句,则需要用括号{}( )把它们括起来。

_ASM {

MOV     AX,data1

XCHG    AX,data2

MOV     datal,AX            //实现整型变量data1data2之值的交换

}

11-7 以二进制到十六进制之间的任意进制显示输入的数值(032767)。

首先,把输入的ASCII数码转换为二进制数;其次,通过循环调用disps函数将该数转换为二进制到十六进制之间的任意进制的ASCII数码再显示出来。

#include<conio.h>

char*buffer="Enter a number between 0 and 32767:";

char*buffer1="Base";

int a,b=0;

//disps子函数功能:将二进制数data转换为base进制数显示

//入口参数:int型的基数baseint型的data

//出口参数:无

//算法描述:除基数取余数法,直至商为0

void disps(int baseint data){

int temp;

_ASM{

MOV  EAX,data

MOV  EBX,base

PUSH EBX

top1:  MOV  EDX,0

DIV  EBX

PUSH EDX

CMP  EAX,0

JNZ top1

top2: POP  EDX

CMP EDX,EBX

JE top4

ADD  EDX,30H

CROP  EDX,39H

JBE top3

ADD  EDX,7

top3:  MOV temp,EDX

}

_putch(temp);

_ASM{JMP top2}

top4:

}

void main(){

int i;

_cputs(buffer);

a=_getche();

while(a>='0'&&a<='9'){

_ASM{sub a,30H}

b=b*10+a;

a=_getche();

}

_putch(10);

_putch(13);

for(i=2;i<17;i++){

_cputs(buffer1);

disps(10,i);

_putch(' ');

disps(I,b);

_putch(10);

_putch(13);

}

}

运行结果如图11-11所示。

11-11  运行结果

11.4.2  C++应用程序中调用汇编语言程序

正如上面提到的,内嵌的汇编器是受限制的,因为它不能使用宏指令和部分伪指令。在有些情况下,开发独立的汇编模块然后再与C++链接,这种方法更灵活。下面通过例子来说明C++如何调用独立的汇编子模块。

11-8 将一字符串反序输出显示。

利用C++实现字符串的显示功能,用汇编模块实现反序功能。

; Reverse子模块功能:将arraychar指向的字符串反序

; 入口参数:char型的指针arraychar

; 出口参数:无

; 算法:逐一取出字符入栈,然后利用堆栈的“后进先出”的存储原则逐一出栈,再从字符的首地

; 址逐一存入

.386

.MODEL    FLAT,c

.STACK    1024

.CODE

public    Reverse

Reverse proc uses ESI,arraychar:ptr

MOV    ESI,arraychar

PUSH 0

.REPEAT

MOV    AL,[ESI]

PUSH    AX

INC    ESI

.UNTIL BYTE PTR[ESI]==0

MOV    ESI,arraychar

.WHILE    1

POP    AX

.BREAK.IF AL==0

MOV    [ESI],AL

INC    ESI

.ENDW

RET

Reverse  ENDP

END

主模块源程序:

#include<iostream.h>

externb "c" void Reverse(char*);

char chararray[30]="This is the mix programme!";

void main(){

cout<<chararray<<'\n';

Reverse(chararray);

cout<<chararray<<'\n';

}

Visual C++ 6.0环境下的实现步骤如下:

1)在“文件”菜单中选择“新建”命令,弹出如图11-12所示的对话框,选择“工程”选项卡中的Win32 Console Application,在“位置”文本框选择存储目录,在“工程名称”文本框中填写项目名,然后单击“确定”按钮。

11-12 “新建”对话框

2)在如图11-13所示的对话框中,选中“一个空工程”单选按钮,然后单击“完成”按钮。

11-13  Win 32 Console Application对话框

3)在“文件”菜单中选择“新建”命令,弹出如图11-12所示的对话框,选择“文件”选项卡中的C++ Source File选项,在“文件名”文本框填写文件名,然后单击“确定”按钮,在此编辑环境输入C++源程序。

4)在“文件”菜单中选择“新建”命令,弹出如图11-12所示的对话框,选择“文件”选项卡中的“文本文件”选项,在“文件名”文本框填写文件名,然后单击“确定”按钮,在此编辑环境输入汇编源程序。

5)在Visual C++ 6.0的“工作区”窗口中右击汇编文件名,在弹出的快捷菜单中选择“设置”命令。

6)在弹出的如图11-14所示的对话框中输入需要的信息后单击“确定”按钮。

11-14  Project Settings对话框

7)在“编译”菜单中选择“重建全部”命令,生成可执行文件。

8)执行程序,结果如图11-15所示。

11-15  运行结果