FB内嵌汇编探索3

三、字符串的使用

    在使用字符串时,发现除了用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”的时候运行结果是:

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

参数为空字符串时,运行的结果是:

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

 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 

你可能感兴趣的:(汇编,c语言,开发语言)