三、字符串的使用
在使用字符串时,发现除了用lea指令加载字符串,或者直接对字符串指针进行mov,还有一种就是用offset来取字符串指针。
Dim Shared s As ZString * 100 = "eeee" '全局变量
Sub test(ByRef a As ZString)
Dim z As ZString * 100 = "123456"
Asm
mov eax,[a] '函数内部的变量
lea esi,[eax] '可以用lea加载指针
mov edi,offset s '全局变量,可以用offset
cmp Byte Ptr [esi],0 '判断参数a是否为空字符串
je testend '是则不改变z
movzx eax,Byte Ptr [edi] '从全局字符串获取一字节
mov [z],al '存储到z
movzx eax,Byte Ptr [esi] '从参数获取以字节
mov [z+1],al '存储到z+1
testend:
End Asm
Print z
End Sub
test("dddd")
Sleep
End
参数为“dddd”的时候运行结果是:
参数为空字符串时,运行的结果是:
2、块移动指令
利用rep movsb指令可以快速的复制字符串。
Dim z As ZString * 20
Asm
'// hello.s
.data
msg: '定义字符串
.ascii "Hello world!\n"
len = . - msg '获取字符串长度
.text
.global _start '函数名_start
_start:
mov ecx,len '字符串长度
mov esi,offset msg
lea edi,[z]
rep movsb 'esi ->edi ,len = ecx
End Asm
Print z
Sleep
End
六、函数里调用子函数
汇编很容易实现子函数的调用,那么FB是不是也可以通过汇编实现函数内部的子函数呢?通过试验发现只要增加3条汇编指令(3个单行asm)就能够实现。试验如下:
#ifndef __FB_64BIT__
#cmdline "-gen gas" '32位默认是gas,所以可以不用这个命令
#else
#cmdline "-gen gas64" '64为默认是gcc,所以需要声明这个命令,否则会被优化掉
#endIf
Sub test()
Dim a As Long = 10
Dim b As Long = 5
Dim c As Long = a + b '实现加法
Print c
Asm call testsubcll '单行汇编,调用子函数
Print c '打印结果
Exit Sub '这里要注意退出函数,以下的都是子函数范围了
'--------------------------------------------------------------------------
'子函数
Asm testsubcll: '设置子函数名(汇编里就是一个标号)
c = a * b '实现乘法,这里就是函数内部,可以直接使用FB语句,同时共用函数的变量
Asm ret '子函数返回
'如果需要,可以实现多个子函数
End Sub
test()
Sleep
End