Asm
 
允许使用特殊指令结构的汇编代码。

语法

Asm
architecture-dependent instructions
End Asm

Or

Asm architecture-dependent instructions

说明

Asm块用于在程序中插入特定的机器码指令,以执行不能使用该语言的功能执行的操作,或手动优化性能敏感的代码段。

目前的FreeBASIC编译器目前只生成基于Intel 80x86机器的代码;然而,将来,编译器可能被移植到不支持相同指令集的平台上。因此,只有在必要时才使用Asm块,并且如果可能,应该提供仅限FreeBASIC的替代方案。

可以使用括号内的Function关键字设置函数的返回值,如下面的示例所示。

Asm块注释与惯例FreeBASIC 注释具有相同的语法 - 使用FreeBASIC类似的“'”注释,而不像“;”一样,在汇编代码中。

x86具体:

句法
内联汇编器的语法是英特尔语法的简化形式。大多数x86汇编程序使用英特尔语法,如MASM,TASM,NASM,YASM和FASM。一般来说,指令的目的地是首先放置,其次是源。由程序定义的变量和函数可以在Asm块中引用。FreeBASIC使用的汇编程序是GAS,使用.intel_syntax noprefix指令,Asm块通过未修改的方式传递,除了替换局部变量名称以进行堆栈帧引用,并注释删除。

指令语法大体上与FASM使用相同,一个重要的区别是GAS需要大小设置后跟“ptr”。

' Assuming "blah" is a FB global or local UINTEGER variable
mov  eax, [blah]        ' OK: size is apparent from eax
inc  [blah]             ' Not OK: size is not given
inc  dword [blah]       ' Not OK: size given, but still not accepted by GAS
inc  dword Ptr [blah]   ' OK: "ptr" is needed by GAS here


注册保存
Asm块打开时,寄存器ebxesiedi被推送到堆栈,当块关闭时,这些寄存器从堆栈中弹回。这是因为大多数或所有OS使用x86 CPU需要保留这些寄存器。因此,您可以自行使用这些寄存器,而无需明确保留它们。您不应该更改espebp,因为它们通常用于解决局部变量。

注册名称
x86架构的寄存器的名称如下写在Asm块中:
      • 4字节整数寄存器:eaxebxecxedx,ebpespediesi
      • 2字节整数寄存器:axbxcxdxbpspdisi(低字节的4字节e - 寄存器)
      • 1字节整数寄存器:alahblbhclchdldh(低字节和高字节的2字节 - x寄存器)
      • 浮点寄存器:st(0)st(1)st(2)st(3)st(4)st(5)st(6)st(7)
      • MMX寄存器(别名到浮点寄存器):mm0mm1mm2mm3mm4mm5mm6mm7
      • SSE寄存器:xmm0xmm1xmm2xmm3xmm4xmm5xmm6xmm7
指令系统

请参阅这些外部参考:
不安全的说明
请注意,FreeBASIC编译器为x86生成32位保护模式代码,通常在非特权用户级别运行;因此,特权和敏感指令将组合良好,但可能无法正常工作或导致运行时“一般保护故障”,“非法指令”或SIGILL错误。以下是Intel Pentium 4和Xeon的特权和敏感指示:
      • cli *1
      • clts
      • hlt
      • in *1
      • ins *1
      • int *1
      • into *1
      • invd
      • invlpg
      • lgdt
      • lidt
      • lldt
      • lmsw
      • ltr
      • movto / from CRn,DRn,TRn
      • out *1
      • outs *1
      • rdmsr
      • rdpmc *2
      • rdtsc *2
      • sti *1
      • str
      • wbinvd
      • wrmsr
      • 所有SSE2及更高版本的说明* 2

* 1:对IOPL敏感,在DOS中很好
* 2:对CR4中的许可位敏感,见下文
当在Ring 0 DPMI内核上运行时,特权指令将在DOS中正常工作,例如(非默认)Ring 0版本的CWSDPMI,WDOSX或D3X,但大部分当从DPMI代码执行时,它们并不真正有用和危险。RDTSC(读时间戳计数器)已经被大多数或所有操作系统所允许。

然而,随着多核和休眠CPU的出现,RDTSC的有用性已经减弱。在CPU初始化之后,SSE2和更高版本的指令被禁用,Windows和Linux通常会启用它们,在DOS中它是DPMI主机的业务:HDPMI32将启用它们,CWSDPMI将不会。INT指令仅在DOS版本/目标下可用,请注意,它与实模式DOS的工作方式略有不同,另见FaqDOS。

不能从Asm块更改分段寄存器(csdsesfsgs),但在某些情况下,DOS端口除外(请注意,它们不工作与实模式DOS相同,另见FaqDOS)。操作系统或DPMI主机负责内存管理;保护模式中段(选择器)的含义与实模式存储器寻址非常不同。

请注意,即使运行权限不足,操作系统或DPMI主机也可以在功能上决定“模拟”这些“不安全”指令,从而引发“可见”崩溃(从HDPMI32的一些CRx工作中读取),或“虚拟”(没有发生任何事情,教学将默认通过,像NOP)。

例子

''这是x86架构的一个例子。
Function AddFive(ByVal num As Integer) As Integer
    Asm
        mov eax, [num]
        add eax, 5
        mov [Function], eax
    End Asm
End Function

Dim i As Integer = 4

Print "4 + 5 ="; AddFive(i)


4 + 5 = 9


FreeBASIC的汇编器是GCC的汇编程序AS / GAS,因此是外部程序。有些怪癖适用:
    • FBC为ASM块返回的错误行与FB源文件无关。由于FBC只显示AS返回的错误,这些行与程序集文件相关。要使FreeBASIC保留它们,必须使用-R 选项(“不要删除ASM文件”)来调用编译器。
    • 标签名称在ASM块内区分大小写。

方言差异

  • -lang qb 方言中不可用,除非使用别名__asm引用。

与QB差别

  • 新的FreeBASIC

参考