FB内嵌汇编探索

    FB语言支持内嵌汇编,使用的是GAS格式汇编,可以通过VFB工程菜单里的保存为独立的GAS格式源码来查看FB与GAS汇编的转换方式。以此摸索内嵌汇编的使用方式。

FB内嵌汇编探索_第1张图片

图1-1 FB源码转汇编源码 

一、变量赋值(MOV等指令)

需要将变量用 [] 符号包含,即可转移或者赋值,例子如下:

Print "内嵌汇编测试"

Dim a As Long = 10,b As Long = 20 
Dim c As Long = 0

'1、操作变量需要加[]
'2、注释必须使用FB的注释符号,使用汇编的注释编译出错
Asm
	mov eax,[a]   '变量a赋值到eax
	Add eax,[b]   'a + b
	mov [c],eax   '将eax赋值到变量c
End Asm

Print a & " + " & b & " = " & c           '打印到控制台

Sleep             '暂停观察
End 

显示效果如下:

FB内嵌汇编探索_第2张图片

二、函数调用

 函数调用需要使用push先把参数压入栈里(如果有参数),根据调用约定不同,压入栈的顺序也有区别,FB里默认有3种调用约定 cdecl、pascal、stdcall,默认是stdcall,可以不用声明。过程不

需要管返回ret,如果是函数,则需要返回,但不能直接在内嵌汇编里返回,需要使用return返回。

Print "内嵌汇编测试"
Print "1、过程的调用"
'1 stdcall - 这个是默认的调用约定,可以不写
Sub add_print1(ByVal a As Long,ByVal b As Long) 
	Dim r As Long
	Asm
		mov eax,[a]
		Add eax,[b]
		mov [r],eax
	End Asm
	Print "stdcall方式[默认]"
	Print a & " + " & b & " = " & r           '打印到控制台
End Sub

'2 cdecl - c语言调用约定,使用C语言库时需要声明
Sub add_print2 Cdecl(ByVal a As Long,ByVal b As Long)
	Dim r As Long
	Asm
		mov eax,[a]
		Add eax,[b]
		mov [r],eax
	End Asm
	Print "cdecl - c语言格式"
	Print a & " + " & b & " = " & r           '打印到控制台
End Sub

'3 pascal - pascal语言调用约定
Sub add_print3 Pascal(ByVal a As Long,ByVal b As Long)
	Dim r As Long
	Asm
		mov eax,[a]
		Add eax,[b]
		mov [r],eax
	End Asm
	Print "pascal - pascal语言格式"
	Print a & " + " & b & " = " & r           '打印到控制台
End Sub

'4 函数调用及返回
Function dec_return(ByVal a As Long,ByVal b As Long) As Long
	Dim r As Long    '返回变量
	If a > b Then
		Asm
			mov eax,[a] 
			Sub eax,[b] 
			mov [r],eax 
		End Asm 		
	Else
		Asm
			mov eax,[b] 
			Add eax,[a] 
			mov [r],eax 
		End Asm 
	EndIf
	Return r        '返回数据
End Function

'过程调用,先用push把参数压入栈中,然后用call调用函数
Dim r As Long
Asm
'过程
	push 10             '参数b = 10
	push 20             '参数a = 20
	Call add_print1      '调用过程
	
	push 10             '参数b = 10
	push 20             '参数a = 20
	Call add_print2      '调用过程
	
	push 10             '参数a = 10
	push 20             '参数b = 20
	Call add_print3      '调用过程
'函数	
	push 10             '参数a = 10
	push 20             '参数b = 20
	Call dec_return      '调用过程
	mov [r],eax
End Asm
    Print "2、函数的调用与返回"
	Print "20 - 10 = " & r           '打印到控制台

Sleep             '暂停观察
End 

显示效果如下:

FB内嵌汇编探索_第3张图片

三、字符串的使用

#include Once "crt/stdio.bi" 'printf函数

Print "内嵌汇编测试"


Dim sz As ZString * 20 = !"hello word!\r\n"       '定义一个字符串
Dim psz As ZString Ptr = @!"test value is %x\r\n" 'printf格式化字符串
Asm
	lea eax,[sz]   '将字符串指针载入eax,需要用lea命令
	push eax       '将字符串指针压入栈中
    Call printf    '调用printf函数 即printf(sz)
    
    mov eax,[psz]  '如果是指针,则直接用mov命令  
    push &HAA      '第二个参数
    push eax       '第一个参数
    Call printf    '调用print函数,即printf("test value is %x\r\n",&HAA)
End Asm


Sleep 

显示效果如下:

FB内嵌汇编探索_第4张图片

四、跳转指令

1、or后跳转

#include Once "crt/stdio.bi" 'printf函数

Print "内嵌汇编测试"
'
Dim EaxEqu As ZString * 10 = "eax = 0"
Dim EaxNotEqu As ZString * 10 = "eax <> 0"

'or后判断,jne,不为0则跳转,为0则顺序执行,如果是je,跳转条件于jne相反
Dim a As Long = 0     '测试a = 0
'Dim a As Long = 1    '    a = 正数
'Dim a As Long = -1   '    a = 负数
    Asm 
    	mov eax,[a]
    	Or eax,eax    '
    	jne nx        '不相等跳转指令 eax <> 0,则跳转;eax = 0,则顺序执行
        lea eax,[EaxEqu]
        jmp ex        '无条件跳转指令
nx:
        lea eax,[EaxNotEqu]
ex:     
        push eax
        Call printf
    End Asm


Sleep 

 运行效果如下:

FB内嵌汇编探索_第5张图片

2、cmp命令跳转

#Define UNICODE
#Include Once "crt/stdio.bi"

Dim ss1 As WString * 10 = WStr(!"相等\r\n")
Dim ss2 As WString * 10 = WStr(!"不相等\r\n")
Dim ss3 As WString * 10 = WStr(!"大于\r\n")
Dim ss4 As WString * 10 = WStr(!"大于等于\r\n")
Dim ss5 As WString * 10 = WStr(!"小于\r\n")
Dim ss6 As WString * 10 = WStr(!"小于等于\r\n")

'Dim a As Long = -1
Dim a As Long = 0
'Dim a As Long = -1

Asm
'je,jne 相等,不相等
	mov eax,[a]
	cmp eax,0
	je  nx
	lea eax,[ss2]
	jmp ex
nx:
    lea eax,[ss1]
ex:
    push eax
    Call wprintf
'jg,jge,jng,jnge 大于,大于等于,不大于,不大于等于    
	mov eax,[a]
	cmp eax,0
	jg  nx1        'jg >,jge >=,jng <=,jnge <
	lea eax,[ss6]
	jmp ex1
nx1:
    lea eax,[ss3]
ex1:
    push eax
    Call wprintf    
'jl,jle,jnl,jnle 小于,小于等于,不小于,不小于等于    
    mov eax,[a]
	cmp eax,0
	jl  nx2        'jl <,jle <=,jnl >=,jnle >
	lea eax,[ss4]
	jmp ex2
nx2:
    lea eax,[ss5]
ex2:
    push eax
    Call wprintf
End Asm

Sleep

 运行效果如下:

FB内嵌汇编探索_第6张图片

 

你可能感兴趣的:(FreeBASIC学习笔记,freebasic,内嵌汇编)