汇编语言与Qbasic语言的接口技术

      编程宝典 2005-6-5 14:41:00

汇编语言没有高级语言要占用较大的存储空间和较长的运行时间等缺点,它的运行速度快是高级语言所不能比拟的。可以说高级语言与汇编语言各有千秋。有时我们采用高级语言编程速度达不到要求,全部采用汇编语言编程工作量又大,此时可以采用"混合"编程,彼此相互调用,进行参数传递,共享数据结构及数据信息,是一种有效的编程方法。这种方法可以发挥各种语言的优势和特点,充分利用现有的多种实用程序、库程序等使软件的开发周期大大缩短。
1 高级语言与汇编语言的接口需要解决的问题
  1、需要说明和建立调用者与被调用者间的关系被调用的过程或函数应预先说明为外部类型,如汇编子程序,应用PUBLIC说明其可被外部模块引用;调用程序则应预先说明要引用的外部模块名。
2、参数传递问题在汇编子程序之间通常采用寄存器作为参数传递的工具,汇编语言与高级语言程序间的参数传递,一般采用堆栈来传递,即调用程序将参数依次压入堆栈中,当被转调用程序后,再从堆栈中依次弹出参数作为操作数使用。为此,必须了解各种语言的堆栈结构、生成方式和入栈方式等。BA SIC、FORTRAN、PASCAL等语言其参数进栈顺序是与参数在参数表中出现的顺序相同,即从右到左
2 basic语言与汇编语言的接口
2.1 qbasic语言调用汇编子程序,有两种方式
A、在程序中使用CALL ABSOLUTE,(这个是直接在QB的源程序中内嵌机器码)
CALL ABSOLUTE address [(参数表)] 传送控制给一个机器语言过程
B、用汇编语言编写,编译,然后用QB的LINK连接成库调用!
(在后面详细解释)
2。2 参数传递
参数传递顺序是按其在参数表中出现的顺序的反序被压入堆栈中,即第一个参数最后进入堆栈,它在栈中的地址最低。
●对不同的存储模式要选用不同的汇编语言格式,如程序为小模式,汇编用近过程,程序为大模式,汇编用远过程。
●汇编程序取QB的参数。远过程返回地址占四个字节,BP压入占二字节,所以第一个参数在BP+6所指向的单元。对于近过程第一个参数在BP+4所指向的单元。
●汇编程序中寄存器的保护。QB允许子过程使用SI和DI存放局部变量,当寄存器变量多于二个时,多余部分会自动转到堆栈中存储。因此,汇编过程的格式为:
PUSH BP
MOV BP,SP
PUSH DI
PUSH SI
……….
语 句
………….
POP SI
POP DI
POP BP
RET
●返回值。每种QB数据类型都有一个标准的返回位置,一般在AX中(模式),DX:AX(大模式),如:char,unsignedchar,enum,shortint等,返回值位置为AX,且返回数据必须放置在RET指令之前。汇编子程序要定义为远过程,并用PUBLIC伪指令把过程名定义为公共。
PUSH BP
MOVBP,SP
PUSH DS
PUSH SI
PUSH DI

POP SI
POP AX
MOV DS,AX
POP BP
MOV AX,CX
RET
Revstr ENDP
END
2.2 QB语言嵌入汇编
CALL ABSOLUTE CALL ABSOLUTE address [(参数表)] 传送控制给一个机器语言过程
QB语言允许嵌入四类汇编命令:一般指令、串指令、跳转指令、数据分配和定义指令,嵌入汇编比调用汇编子程序更方便、灵活、功能也更强。但嵌入汇编不是一个完整的汇编程序,所以许多错误不能马上检查出来。
3 结 束 语
采用两种或两种以上的编程语言组合编程,彼此相互调用,进行参数传递,是一种有效的程序设计方法。这种方法可以充分发挥各种语言的优势,充分利用现有的实用程序,是当前程序接口技术的一个重要研究和应用领域。


下面是一个详细的例子:调用鼠标用的是汇编!启动请用qb/l
这个程序不是我写的
DIM SHARED mouser$, JoyXPos, JoyYPos, but1%, but2%, but3%, but4%,
MouseLeftButton, MouseRightButton, MouseXPos, MouseYPos, AX%, bx%, cx%, dx%
SCREEN 12

Mouse 0

CLS

DO

'Mouse Routines
Mouse 3
LOCATE 2, 1
PRINT "Mouse "
PRINT " Left Button :"; MouseLeftButton
PRINT " Right Button:"; MouseRightButton
PRINT " X Position:"; MouseXPos
PRINT " Y Position:"; MouseYPos
PRINT
PRINT

'Joystick Routines (Beware, they slow your program down alot!)
' (Plus a calibration program needs to be build)
' (I don't have enough time to do it!)

STICKS
PRINT "Joystick "
PRINT " Button 1:"; but1%
PRINT " Button 2:"; but2%
PRINT " Button 3:"; but3%
PRINT " Button 4:"; but4%
PRINT " X Position:"; JoyXPos
PRINT " Y Position:"; JoyYPos

LOOP

DATA 55,89,E5,8B,5E,0C,8B,07,50,8B,5E,0A,8B,07,50,8B
DATA 5E,08,8B,0F,8B,5E,06,8B,17,5B,58,1E,07,CD,33,53
DATA 8B,5E,0C,89,07,58,8B,5E,0A,89,07,8B,5E,08,89,0F
DATA 8B,5E,06,89,17,5D,CA,08,00

SUB Mouse (which)
'0 = Mouse Init
'1 = Mouse Driver
'2 = Mouse Put
'3 = Mouse Status
'4 = Mouse Hide
'5 = Mouse Show
IF which = 0 THEN
mouser$ = SPACE$(57)
FOR I% = 1 TO 57
READ A$
H$ = CHR$(VAL("&H" + A$))
MID$(mouser$, I%, 1) = H$
NEXT I%
AX% = 0
bx% = 0
cx% = 0
dx% = 0
Mouse 1
MouseInit% = AX%
Mouse 5
END IF
IF which = 1 THEN
DEF SEG = VARSEG(mouser$)
mouser% = SADD(mouser$)
CALL Absolute(AX%, bx%, cx%, dx%, mouser%)
END IF
IF which = 2 THEN
AX% = 4
cx% = X%
dx% = Y%
bx% = 0
Mouse 1
END IF
IF which = 3 THEN
AX% = 3
Mouse 1
MouseLeftButton = ((bx% AND 1) <> 0)
MouseRightButton = ((bx% AND 2) <> 0)
MouseXPos = cx%
MouseYPos = dx%
END IF
IF which = 4 THEN
AX% = 2
bx% = 0
cx% = 0
dx% = 0
Mouse 1
END IF
IF which = 5 THEN
AX% = 1
bx% = 0
cx% = 0
dx% = 0
Mouse 1
END IF
END SUB

SUB STICKS
JoyXPos = STICK(0)
JoyYPos = STICK(1)
but1% = STRIG(0)
but2% = STRIG(2)
but3% = STRIG(4)
but4% = STRIG(6)
END SUB

上面这个程序中DATA中的数据被程序转成了机器码,我把它翻译成汇编了,让大家仔细的看看!
机器码 汇编语言
55 PUSH BP
89E5 MOV BP,SP
8B5E0C MOV BX,[BP+0C]
8B07 MOV AX,[BX]
50 PUSH AX
8B5E0A MOV BX,[BP+0A]
8B07 MOV AX,[BX]
50 PUSH AX
8B5E08 MOV BX,[BP+08]
8B0F MOV CX,[BX]
8B5E06 MOV BX,[BP+06]
8B17 MOV DX,[BX]
5B POP BX
58 POP AX
1E PUSH DS
07 POP ES
CD33 INT 33
53 PUSH BX
8B5E0C MOV BX,[BP+0C]
8907 MOV [BX],AX
58 POP AX
8B5E0A MOV BX,[BP+0A]
8907 MOV [BX],AX
8B5E08 MOV BX,[BP+08]
890F MOV [BX],CX
8B5E06 MOV BX,[BP+06]
8917 MOV [BX],DX
5D POP BP
CA0800 RETF 0008


二、用汇编语言编写,编译,然后用QB的LINK连接成库调用!
例如:(MASM 5.0 QB4.5 )
有个汇编程序是取键码值的!
名字为 DEMO.ASM,内容如下:
dosseg
.model medium
.stack 100h
public scankey
.code
scankey proc far
push bp
mov bp,sp
mov ah,0
int 16h
mov di,[bp]+8
mov [di],ah
mov di,[bp]+6
mov [di],al
pop bp
ret 4
scankey endp
end
输入MASM
在提示下输入DEMO.ASM
得到DEMO.OBJ
复制到QB的目录
LINK /Q DEMO.OBJ
在提示[.LIB]的时候键入 BQLB45.LIB
这样就得到一个库DEMO.QLB
用法:
启动是键入: QB/L DEMO.QLB
例 程序
CALL SCANKEY(K1%,K2%)
PRINT K1%,K2%
呵呵,很简单吧!
QB与C的连接也差不多,在开始的声明中不一样!
这样的话,我们就可以实现多语言的共同协作!





标签集:TAGS:
回复Comments() 点击Count()
喜欢就顶一下

回复Comments

{commentauthor}
{commentauthor}
{commenttime}
{commentnum}
{commentcontent}
作者:
{commentrecontent}