FB使用汇编模拟GoSub(子函数)功能

    在FB里不支持GoSub功能,在面对函数内简单又重复的操作,而所涉及变量又比较多的时候,再在外边定义一个函数就显得累赘,此时如果可以有一个函数内部的子函数,就显得方便多了。

    在汇编探索里发现,可以使用汇编来实现函数的子函数功能,但gcc编译的时候,会把子函数部分当做无效代码优化了,通过测试发现,只要用汇编跳转到函数末尾,则gcc编译器就不会直接优化子函数代码了。于是设置了3个宏,来实现FB的GoSub功能。

1、GotoSub(fn)

宏定义如下,用汇编的call来调用子函数,参数是函数名称。

#Macro GotoSub(fn)
Asm
	call	fn
End Asm
#EndMacro

2、SubName(fn)

宏定义如下,就是定义一个函数的标签,参数是函数名称。(只能通过汇编来调用(call)或者跳转(jmp),goto是不行的)

#Macro SubName(fn)
Asm
fn:
End Asm
#EndMacro

3、RetSub

宏定义如下,就是汇编的返回(ret)。作为子函数时,必须要有返回,不然不能回到原来函数调用的地方。

#Macro RetSub
Asm
	ret
End Asm
#EndMacro

具体实现过程如下:

#include Once "windows.bi"

#Macro GotoSub(fn)
Asm
	call	fn
End Asm
#EndMacro

#Macro SubName(fn)
Asm
fn:
End Asm
#EndMacro

#Macro RetSub
Asm
	ret
End Asm
#EndMacro


Sub test()
	Dim a As Long = 10
	Dim b As Long = 5
	Dim c As Long = 0
	c = a + b
	GotoSub(test2) 		'打印输出
	GotoSub(test1)		'乘法计算
	GotoSub(test2) 		'打印输出
'--------------------------------------------------	
'跳到函数末尾
'  这里不能用exit sub,exit function,return和goto来结束函数,
'  因为如果使用gcc编译的时候,使用以上方法结束函数,子函数部分会被优化。
'  只能使用汇编来跳转到末尾
	GotoSub(testend) 	
'--------------------------------------------------
'子函数1 算乘法
SubName(test1)			'子函数名
	c = a * b
	RetSub				'必须有返回,不然就会顺序往下执行
'--------------------------------------------------
'子函数2 单纯的打印c功能
SubName(test2)
	Print "c = ";c
	RetSub
'--------------------------------------------------
'函数末尾	
SubName(testend)		
End Sub

test()

Sleep
End

必须注意:

1、如果使用子函数,必须有在原有函数主体程序末尾加一个跳转到函数结尾的调用。建议使用函数名+end实现。如GotoSub(testend) 。同时在函数末尾(end sub或者end function前)定义一个函数名,如SubName(testend)。此函数不返回。

2、其他子函数都是使用函数名SubName + 返回RetSub的方式来实现。

3、根据需要也可以不写,比如同时执行a函数+b函数,以及可以单独调用b函数时,a函数放前面,不返回,b函数返回。

你可能感兴趣的:(FreeBASIC随记,freebasic,gosub,子函数)