本文档的用户手册是Yasm汇编。 它是介绍和通用所有Yasm用户参考。

英文的参考:http://www.cnblogs.com/coryxie/p/3959888.html

1 .介绍

Yasm bsd许可下是一个汇编程序,而设计的,以便支持多个汇编程序语法(例如NASM,GNU等)除了多个输出对象格式和多个指令集。 其模块化的体系结构允许额外的对象格式,添加调试格式和语法相对容易。

Yasm 2001年开始生活的重写NASM Netwide x86汇编在BSD许可。 自那时以来,它已经达到和超过NASM的功能,结合特性,比如支持64位AMD64架构,解析GNU语法,并生成刺穿,DWARF2 CodeView 8调试信息。

2 .许可证

Yasm许可2-clause下3条款“修订”BSD许可,但有一个例外:::矢量模块使用的主线版本的Yasm实现独立于机器大整数和浮点支持下triple-licensed艺术许可证GPL,LGPL。 “yasm-nextgen”代码使用一个完全不同的bsd许可下实现,因此在BSD-equivalent许可证。 提供的许可证的全文Yasm源分布。

这个用户手册2-clause BSD许可下的。

3所示。 材料覆盖在这本书

我一部分。 使用Yasm

所说yasm简介

infile }

1.2描述。

都是确定的。

(通常终端)。 如果没有遇到错误或警告,Yasm不输出任何信息。

选择1.3。

许多选项可以在两种形式之一:破折号后面跟着一个字母,或者两个破折号,后跟一个长选项名称。 按字母顺序列出选项。

1.3.1。 一般选择

:选择目标架构

的支持架构。

:选择对象格式

支持的对象列表格式。

:选择调试格式

支持的调试格式列表。

:打印选项的摘要

打印的摘要调用选项。 所有其他选项都被忽略,没有生成输出文件。

文件格式:选择列表

:指定文件名列表

指定输出文件列表的名称。 如果不使用此选项,没有生成文件列表。

:选择目标计算机体系结构

为更多的细节。

对象:指定文件名

指定输出文件的名称,覆盖任何Yasm生成的缺省名称。

:选择解析器

支持的解析器列表。

:选择预处理器

:Yasm版本

这个选项会导致Yasm打印的版本号Yasm以及许可证总结到标准输出。 所有其他选项都被忽略,没有生成输出文件。

1.3.2。 警告选项

。 这里只显示了非默认形式。

orphan-labels。

:抑制所有的警告消息

这个选项会导致Yasm抑制所有警告消息。 正如上面所讨论的,这个选项可以指定其他选项重新启用警告紧随其后。

:将警告视为错误

,而错误。 这个选项让警告相当于错误的这种行为。

:不要警告未识别的输入字符

导致Yasm不警告无法识别的字符输入。 通常Yasm将生成一个警告任何非ascii字符输入文件中找到。

末尾:警告标签上缺少冒号

当使用NASM-compatible解析器,使Yasm警告标签发现独自一行末尾没有冒号。 虽然这些是合法的标签在NASM中语法,他们可能是无意的,由于拼写错误或宏定义命令。

:改变错误/警告报告风格

。 的“vc”风格也可以模仿微软Visual Studio的编译器的输出。

,允许IDE正确认识到错误/警告信息等,并链接到的违规行源代码。

1.3.3。 预处理器的选择

虽然理论上这些预处理选项将影响任何预处理器,目前唯一的预处理器在Yasm nasm预处理器。

:预定义宏

预定义一个单行的宏。 值是可选的(如果没有赋值,宏仍然是定义,但是一个空值)。

:只有进行预处理

停止组装后的预处理阶段;预处理输出发送到指定的输出名称或,如果没有指定输出名称,标准输出。 不产生目标文件。

:添加包含文件路径

包括文件的搜索路径。 搜索路径默认为只包括源文件所在的目录。

:Pre-include文件

不能支持。

:未定义一个宏

)。

1.4。 支持目标架构

Yasm支持以下指令集架构(isa)。 更多细节见 

x86

“x86体系结构支持ia - 32指令集和衍生品(包括16位和non-Intel指令)和AMD64指令集。它由两台机器:“x86”(ia - 32和衍生品)和“AMD64”(AMD64和衍生品)。 默认的机器“x86架构的x86机器。

1.5。 支持解析器(语法)

Yasm解析汇编程序语法如下:

nasm

NASM语法是最Yasm全功能的语法支持。 Yasm近100%兼容NASM对16位和32位x86代码。 Yasm另外支持64位AMD64代码与NASM Yasm扩展语法。 更多细节见 

气体

1.6。 支持对象格式

Yasm支持以下对象格式。 可以找到更多的细节 

“本”对象格式生成一个扁平格式,non-relocatable二进制文件。 它是适合生产DOS。 COM可执行文件或引导块之类的东西。 它只支持3部分,这些部分都写在一个预定义的输出文件。

coff

COFF对象格式是一个年长的浮动对象格式用于旧的Unix和兼容系统,以及(最近)DJGPP DOS开发系统。

dbg

“dbg”对象格式不是“真正的”对象格式,其创建的输出文件简单地描述的顺序调用它Yasm和最终的对象和人类可读的文本格式符号表信息(在一个正常的对象格式会加工成对象格式的特定的二进制表示)。 这个对象格式不是为了真正的使用,而是用于调试Yasm内部。

精灵

ELF对象格式真的有三种口味:并且借助elf32””(32位的目标),“elf64”(64位目标),和“elfx32”(x32目标)。 精灵是一个标准的对象格式常用的现代Unix和兼容的系统(例如Linux,FreeBSD)。 精灵已经复杂的支持浮动和共享对象。

男子气概

Mach-O对象格式真的有两种味道:“macho32”(32位的目标)和“macho64”(对于64位目标)。 Mach-O用作对象格式在MacOS x Yasm目前只支持x86和AMD64指令集,它只能为基于英特尔处理器的mac电脑上生成Mach-O对象。

rdf

RDOFF2对象格式是一个简单的多节格式NASM的最初设计。 它支持段引用但不是关于引用。 它的主要目的是简单和简约的标题为便于加载和链接。 一个完整的工具链(链接器、图书管理员和装入器)与NASM分布。

win32

Win32对象生成对象文件格式兼容微软编译器(例如Visual Studio)的32位x86 Windows平台。 COFF的对象格式本身是一个扩展的版本。

win64

Win64对象生成对象文件格式兼容微软编译器,目标64位Windows平台“x64”。 这种格式非常类似于win32对象格式,但64位生成对象。

xdf

XDF对象本质上是一个简化版的COFF格式。 这是一个多节浮动格式,支持64位的物理和虚拟地址。

1.7。 支持调试格式

Yasm支持一代的源代码级调试信息在以下格式。 可以找到更多的细节 

cv8

Win64对象的部分文件。

dwarf2

编译器),也可以生成程序行号信息。

“零”调试格式是一个占位符,它将没有调试信息添加到输出文件。

刺穿了

刺穿了调试格式是一个糟糕的记录,半标准COFF和ELF目标文件格式的调试信息。 调试信息存储对象文件的符号表的一部分,因此在复杂性和范围是有限的。 尽管如此,刺穿了是一种常见的调试格式在旧的Unix和兼容系统,以及DJGPP。

第二章。 VSYASM——Yasm微软Visual Studio 2010

表的内容

2.1。 集成的步骤

2.2。 替代集成步骤

2.3。 使用VSYASM

Visual Studio 2010在一个健壮的和有效的方式。 VSYASM和其他版本之间的主要区别是,它能够组装多个源代码文件在一个命令行。

工具。 在这种情况下,唯一的变化是,VSYASM不仅仅提供预处理模式。

如果VSYASM命令行包括多个源文件,任何输出,列表和地图路径解析命令行上给出的目录组件单独和每个源代码文件然后组装使用这些目录相关的输出。 在大会开始之前,任何不存在VSYASM输出递归创建所需的目录。 装配过程本身停止如果任何文件被组装生成错误。

命令行开关可以用来发送错误报告文件,在这种情况下,这个文件还包括用于调用VSYASM命令行。 这提供了一种方法来检查VSYASM被称为正确Visual Studio构建过程的控制。

2.1。 集成的步骤

)应该被添加到Visual Studio目录C工具。 这通常是:

C:\Program Files (x86)\Microsoft Visual Studio 10.0 \ VC \ bin

——应该添加到项目的项目目录中使用VSYASM(另一个将在稍后解释)。

你把在项目目录,将它添加到列表中选择它,然后从列表中选择它。

一旦你这样做了,在解决方案资源管理器中右键单击该项目并选择“属性”会弹出一个对话,一个新项“Yasm汇编程序”,将允许您配置Yasm构建任何汇编文件添加到项目中。

2.2。 替代集成步骤

如果你有使用VSYASM的很多项目,你可以把上面提到的三个文件放到MSBUILD的构建定制目录通常是在:

C:\Program Files (x86)\MSBuild\ Microsoft.Cpp \ v4.0 \ BuildCustomizations

VSYASM将总是可用在构建自定义对话。 一个替代的方法是把这些文件放在一个方便的位置,然后将这个位置的路径添加到“构建自定义搜索路径”项下“vc++项目设置”在Visual Studio 2010中选择对话。

2.3。 使用VSYASM

在Visual Studio项目汇编源代码文件,Yasm设置中的“Yasm汇编程序”项中输入的项目属性对话。 可用的物品符合那些Yasm上可用的命令行和主要是自我解释但一项——“对象文件名”——确实需要进一步解释。

例如,如“$(IntDir)%(文件名).obj”。

第二部分。 NASM语法

书的这一部分文档中的章节NASM-compatible语法接受Yasm“nasm”解析器和预处理器。

3.1。 NASM源代码行布局

像大多数汇编、每个NASM源线包含(除非它是一个宏,预处理程序指令或一个汇编指令:明白了 一些组合的四个字段

标签:指令操作数;发表评论

像往常一样,这些字段是可选的;任何组合的存在与否的一个标签,一个指令和一个评论是被允许的。 当然,操作数的字段是必需的或禁止的存在和性质教学领域。

NASM使用反斜杠(\)行连续字符;如果一行与反斜杠结束,下一行被认为是backslash-ended线的一部分。

将导致它提醒你如果你定义一个标签单独在一行末尾没有冒号。

), _ 和 吗? 。 一个标识符也可以用一个前缀 美元 表明它的目的是被解读为一个标识符,而不是保留字;因此,如果其他模块你链接定义了一个称为象征 eax ,你可以参考 eax美元 在NASM中代码来区分的标志寄存器。

可以出现在一行本身,NASM只会生成前缀字节。

除了实际的机器指令,NASM还支持许多伪指令,所描述的 

)。

浮点指令,NASM接受广泛的语法:您可以使用two-operand形式像MASM支持实现,或者您可以使用NASM的本机single-operand形式在大多数情况下。 例如,您可以代码:

fadd相约;这集st0:= st0 +相约

fadd st0,相约;这也是如此

 

fadd相约,st0;这集相约:=相约+ st0

fadd相约;这也是如此

表明什么大小的((内存操作数)),它是指。

3.2伪指令。

伪指令的东西,虽然不是真正的x86机器指令,用于教学领域还是因为这是最方便的地方。 当前的 前缀。

和朋友:宣布初始化数据

用于声明输出文件中的数据初始化。 他们以各种各样的方式可以调用:

db 0 x55;只是x55字节0

db 0 x55 0 x56 0 x57;连续三个字节

db ' a ',0 x55;字符常量就可以了

10 db‘你好’,13日,“美元”,所以是字符串常量

dw 0 x1234;0 x34 0 x12

dw ' a ',0 x41 0 x00(它只是一个数字)

dw“ab”;0 x41 0×(字符常数)

dw“abc”;0 x41 0×0 x43 0 x00(字符串)

dd 0 x12345678;0 x78 0 x56 0 0 x12 x34

dq 0 x1122334455667788;0 x88 0 x77 0 x66 0 x55 0 x44 0 x33 0将0 x11

ddq 0 x112233445566778899aabbccddeeff00

;0 x00 0 xff 0 xee xdd 0 xcc 0 xbb 0 xaa 0 x99

;0 x88 0 x77 0 x66 0 x55 0 x44 0 x33 0将0 x11

和以前一样做0 x112233445566778899aabbccddeeff00;

dd 1.234567 e20;浮点常量

dq 1.234567 e20;双精度浮点数

dt 1.234567 e20;给出自由浮动

不接受字符串作为操作数。

和朋友:声明未初始化的数据

例如:

缓冲区:resb 64;储备64字节

wordvar:resw 1;储备一个字

realarray resq 10;十实数数组

:包括外部的二进制文件

件的数据。 它可以调用其中的一个方法:

incbin”文件。 dat”;包含整个文件

incbin”文件。 dat ",1024年,跳过第一个1024字节

incbin”文件。 dat ",1024年,1024年,跳过第一个1024年

实际上,包括最多512

:定义常量

是定义给定的标签名称(只)操作数的值。 这个定义是绝对的,不能改变。 举个例子,

db消息“hello,world”

美元msglen装备的消息

)。

:重复指令或数据

MASM-compatible汇编、语法支持的代码

zerobuf:* 64分贝0

,所以你能做的事情

缓冲区:db“hello,world”

乘以64美元+缓冲db ' '

它展开循环:

乘以100 movsb

,除了后者将快100倍的组装将汇编程序的内部结构。

)。

指令。

3.3。 有效的地址

一个 有效地址是引用内存的任何指令的操作数。 有效的地址,在NASM中,有一个非常简单的语法:他们由一个表达式评估所需的地址,封闭 方括号。 例如:

wordvar dw 123

mov ax,[wordvar]

mov ax,wordvar + 1

mov ax,[西文wordvar + bx):

更复杂的有效地址,如涉及多个寄存器,在完全相同的方式工作:

mov eax,(ebx * 2 +连成一片+偏移量)

mov ax,bp + di + 8

NASM就是这样做的能力 法律非常好:

mov eax,(ebx * 5),组装(ebx * 4 + ebx)

mov eax,label1 * 2-label2;即[label1 +(label1-label2)]

,NASM通常会生成后者,因为前者需要4个字节来存储一个零偏移量。

有不同的默认段寄存器。

例如这样的代码片段)通过使用 (字节eax +偏移量) 。 作为特殊情况, (字节eax) 将代码 (eax + 0) 字节偏移量为0, (dword eax) 将代码用双字抵消为零。 正常的形式, (eax) 将编码没有抵消。

前面的段落中描述的形式也很有用,如果你试图在一个32位访问数据从在16位代码段。 特别是,如果您需要访问数据与一个已知的抵消比适合在一个16位值大,如果你不指定,它是一个dword抵消,NASM将导致高抵消损失。

生成。

3.3.1。 64位的位移

。 在NASM中语法的例子:

mov eax,[1];32位,符号扩展

mov,[rax-1];32位,符号扩展

mov,[qword 0 x1122334455667788];64位绝对的

mov,[0 x1122334455667788];截断32位(警告)

相对寻址

是指令指针寄存器,它包含的地址位置紧跟当前指令)。

在NASM中语法,有两种方法可以指定RIP-relative寻址:

mov dword(rip + 10),1

也可以是象征性的常数,并将以同样的方式对待。 另一方面,

mov dword[symb关于撕裂),1

。 这是明显不同的行为:

mov dword symb +撕裂,1

变量!

相对地址:

mov rel信谊,伸展;RIP-relative

mov abs信谊,伸展,没有RIP-relative

),如下所示。 在Yasm创业总是默认模式 腹肌 ,在 REL 模式,使用寄存器, FS 或 GS 段覆盖,或一个显式的 腹肌 覆盖将导致non-RIP-relative有效地址。

默认rel

mov(对称),rbx;RIP-relative

mov abs信谊,rbx;不是RIP-relative(显式重写)

mov[rbx + 1],rbx;不是RIP-relative(寄存器使用)

mov[fs:信谊],rbx;不是RIP-relative(fs或gs使用)

mov ds:信谊,rbx;RIP-relative(段,但不是fs或gs)

mov rel信谊,rbx;RIP-relative(冗余覆盖)

 

默认的腹肌

mov(对称),rbx;不是RIP-relative

mov abs信谊,rbx;不是RIP-relative

mov[rbx + 1],rbx;不是RIP-relative

mov[fs:信谊],rbx;不是RIP-relative

mov ds:信谊,rbx;不是RIP-relative

mov rel信谊,rbx;RIP-relative(显式重写)

3.4。 直接操作数

关键词,分别。

模式。 对于所有其他指令在64位模式下,立即值仍然是32位,他们的价值符号扩展到32位的目标寄存器之前被使用。 例外是mov指令,可以把一个64位的直接目标是一个64位的寄存器。

关键字。 使用的方便性,Yasm还将试图识别64位值和自动改变大小64位这些情况。

在NASM中语法的例子:

添加递交1;优化签署了8位

添加伸展,dword 1;迫使大小32位

添加伸展,0 xffffffff;符号扩展32位

添加递交1;同上

加伸展,0 xffffffffffffffff;截断32位(警告)

mov eax,1;5字节

mov伸展,1、5字节(32位)签署的优化

mov伸展,qword 1;10字节(64位)

mov rbx,0 x1234567890abcdef;10字节

mov rcx,0 xffffffff;10个字节(32位)签署不符合

mov连成一片,1;5字节,相当于上面

mov rcx,信谊;5字节,32位大小默认符号

mov rcx,qword sym;10字节,覆盖默认大小

谨慎的用户使用NASM和Yasm 2。 x:mov reg64的处理,未分级立即Yasm NASM 2之间是不同的。 x;YASM遵循上述行为,NASM 2。 x是以下几点:

添加伸展,0 xffffffff;符号扩展32位立即

添加递交1;同上

添加伸展,0 xffffffffffffffff;截断32位(警告)

添加伸展,信谊;符号扩展32位立即

立即mov eax,1、5字节(32位)

mov递交1;10字节立即(64位)

mov rbx,0 x1234567890abcdef;10字节的指令

mov rcx,0 xffffffff;10字节的指令

mov连成一片,1;5字节,相当于上面

立即mov连成一片,对称;5字节(32位)

mov rcx,信谊;10字节(64位直接)

mov rcx,qword sym;10字节,同上

3.5 .常量

NASM理解四个不同类型的常数:数字、字符、字符串和浮点。

3.5.1。 数字常量

),所以一个十六进制数字前缀 美元 签署后必须有一个数字 美元 而不是一个字母。

一些例子:

mov ax,100;小数

mov ax,0 a2h;十六进制

mov ax,$ 0 a2;又十六进制:0是必需的

再次mov ax,0 xa2;十六进制

mov ax,777 q;八进制

mov ax,777 o;八进制

mov ax,10010011 b,二进制

3.5.2。 字符常量

字符常量由四字符括在单引号或双引号。 NASM的类型引用没有区别,当然,除了周围不断允许双引号和单引号出现在它,反之亦然。

一个常数与多个字符将安排 低位优先顺序记住:如果你的代码

mov eax,“abcd”

指令。

3.5.3。 字符串常量

字符串常量看起来像一个字符常数,只长。 视为一个连接的最大大小字符常量的条件。 所以以下是等价的:

db‘你好’,字符串常量

db‘h’,‘e’,‘l’,‘l’,‘o’;等效字符常量

和下面的也相当于:

dd ninechars,双字串常数

dd“9”,“字符”,“年代”,变成了三个双字

db ninechars,0,0,0,真的是这样的

3.5.4。 浮点型常量

声明一个浮点型常量。

一些例子:

dw -0.5;IEEE一半精度

dd 1.2;一个简单的

dq - 1。 e10,10000000000

dq - 1。 e + 10;1. e10的同义词

dq - 1。 平台以及;0.000 000 000 1

dt 3.141592653589793238462;π

NASM无法编译时算术浮点常量。 这是因为NASM被设计成便携式——尽管它总是生成代码运行在x86处理器,汇编程序本身可以在任何系统上运行的ANSI C编译器。 因此,汇编程序不能保证的浮点单元处理的能力 英特尔数字格式,所以NASM能够做浮动算术它必须包括自己的成套浮点例程,这将大大增加很少好处的汇编程序的大小。

3.6 .表达式

表达式在NASM中在语法与C是相似的。

32位的工作。

算术 运营商提供的NASM列出,递增的顺序 优先级。

:按位或运算符

机器指令。 按位或NASM支持的优先级运算符。

:按位异或运算符

按位异或操作。

:按位与运算符

位和操作。

:移位操作符

无符号,从左端位转移充满了零而不是符号扩展之前的最高位。

:加法和减法运算符

减法。

:乘法和除法

模运算符。

NASM ANSI C一样,没有提供担保的合理的操作签名模运算符。

性格是广泛使用的宏观预处理器,您应该确保签署和无符号模运算符都是紧随其后的是空白。

赛格

)。

关于

在编写大型16位程序时,必须分成多个 操作符来执行这个函数。

段的一个符号,定义为段基础的相对偏移的象征意义。 因此代码

mov ax,凹陷的象征

mov,斧头

mov bx,象征

东西可以比这更复杂:因为16位段 (参照)关键字。 所以你能做的事情

mov ax,weird_seg;weird_seg段基地

mov,斧头

关于mov bx,象征weird_seg

表示立即值。 所以打电话给一个程序,你可以代码

调用(赛格过程):过程

叫weird_seg:(过程关于weird_seg)

(包括括号是为了清楚起见,显示意图解析上述指令。 他们在实践中则不需要。)

在这些例子中。

声明一个 指针指向一个数据项在数据段中,你必须的代码

dw的象征,凹陷的象征

NASM支持没有方便的同义词,尽管你可以发明一个使用宏处理器。

:抑制优化

模式,

推动dword 33

,而

推动严格dword 33

3.8。 关键表达式

NASM的局限性在于,它是一个 双行程汇编;与TASM和其他人不同,它总是会做两个 大会通过。 因此不能应付复杂到需要源文件,三个或更多 传球。

第一遍是用来确定所有组装的代码和数据的大小,所以第二步,当生成的所有代码,知道所有的符号地址指的代码。 所以NASM无法处理的一件事是代码的值,其大小取决于一个象征宣布后的代码问题。 例如,

*(标签-美元)db 0

标签:db“我在哪儿?”

当它第一次见到它。 它将同样坚定拒绝slightlyparadoxical代码

(标签- $ + 1)db 0

标签:db“现在我在哪儿?”

参数是由定义错了!

伪指令的家庭也关键表达式。

关键表达式可以出现在其他上下文:考虑下面的代码。

mov ax,symbol1

symbol2 symbol1装备

symbol2:

,但那时就太晚了。

将在第一遍被拒绝。

有一个涉及相关问题 向前引用:考虑这个代码片段。

mov eax,ebx +偏移量

抵消装备的10

3.9。 当地的标签

NASM给符号开始的特殊待遇 标签,这意味着它与前面的非本地标签。 举个例子:

label1;一些代码

。 循环;更多的代码

jne .loop

受潮湿腐烂

label2;一些代码

。 循环;更多的代码

jne .loop

受潮湿腐烂

是分开的每一个与前面的非本地标签。

。 所以,如果你真的需要,你可以写

label3;更多的代码

,更多的

jmp label1.loop

,那么它无助于当地标签机制。 所以你可以代码

label1:;非本地标签

。 本地:,这是真的label1.local

. . @foo:,这是一个特殊的符号

label2:;另一个非本地标签

。 本地:,这是真的label2.local

人民币. . @foo;这将跳三行

输出格式。

第四章。 NASM预处理器

表的内容

4.1。 单行的宏

%定义

% xdefine

% +

% undef

%分配

4.2。 字符串处理在宏

% strlen

%的子串

4.3。 多行宏

4.3.1。 重载多行宏

4.3.2。 Macro-Local标签

4.3.3。 贪婪的宏参数

4.3.4。 默认宏参数

柜台:宏参数

:旋转宏参数

4.3.7。 连接宏参数

为4.3.8。 码作为宏观参数条件

4.3.9。 禁用清单扩张

4.4。 有条件的组装

:测试单行的宏观的存在

:测试多行宏观的存在

:测试上下文堆栈

:测试任意数值表达式

:测试具体文本的身份

:测试令牌类型

:用户定义的错误报告

4.5。 预处理程序循环

4.6。 包括其他文件

4.7。 上下文堆栈

:创建和删除背景

4.7.2。 Context-Local标签

4.7.3。 Context-Local单行的宏

:重命名上下文

4.7.5。 IFs示例使用上下文堆栈:块

4.8。 标准宏

等:Yasm版本

:文件名和行号

关键字:输出对象格式

:声明结构数据类型

:声明实例的结构

:数据对齐

的迹象。

预处理程序崩溃所有行最后一个反斜杠(\)字符到一行。 因此:

%定义THIS_VERY_LONG_MACRO_NAME_IS_DEFINED_TO \

THIS_VALUE

将像一个单行的宏没有backslash-newline序列。

4.1。 单行的宏

%定义

预处理器指令。 定义工作类似于C,所以你能做的事情

%定义ctrl 0 x1f &

%定义参数(a,b)(()+()*(b))

 

mov byte[参数(ebx)],ctrl ' D '

这将扩大到

mov byte[(2)+(2)*(ebx)],0 x1f & ' D '

当一个单行的宏观的扩张包含标记调用另一个宏,扩张是在调用时执行,而不是在定义的时间。 因此,代码

%定义(x)1 + b(x)

%定义b(x)2 * x

 

mov ax,(8)

有一个机制,检测宏调用时发生的前一个扩张的宏观,防范 循环引用,无限循环。 如果发生这种情况,预处理器只会扩大宏的第一次出现。 因此,如果你的代码

%定义(x)1 +(x)

 

mov ax,(3)

,然后没有进一步扩张。 这种行为可以是有用的。

你可以超载单行的宏:如果你写

%定义foo(x)1 + x

%定义foo(x,y)1 + x * y

。 然而,如果您定义

%定义foo酒吧

参数,反之亦然。

:你可以很好地定义一个宏

%定义foo酒吧

然后重新定义在相同的源文件

%定义foo巴兹

)。

% xdefine

假设你有下面的代码:

%定义isTrue 1

%定义isFalse isTrue

%定义isTrue 0

 

val1:db isFalse

 

%定义isTrue 1

 

val2:db isFalse

。 它被称为是0,第一次和第二次是1。

% xdefine isTrue 1

% xdefine isFalse isTrue

% xdefine isTrue 0

 

val1:db isFalse

 

% xdefine isTrue 1

 

val2:db isFalse

被定义。

% +

个人令牌一行宏可以连接,生产时间标记为以后处理。 这可能是有用的,如果有几个类似宏执行类似的功能。

作为一个例子,考虑以下:

%定义BDASTART 400 h;BIOS数据区域的开始

 

struc tBIOSDA;它的结构

。 COM1addr RESW 1

。 COM2addr RESW 1

,. . 等等

endstruc

现在,如果我们需要访问tBIOSDA的元素在不同的地方,我们可以得到:

mov ax,BDASTART + tBIOSDA.COM1addr

mov bx,BDASTART + tBIOSDA.COM2addr

这将变得很丑(乏味)如果使用在许多地方,可以显著缩小,通过使用以下宏:

;宏观BIOS变量的访问他们的名字(从tBDA):

 

%定义BDA(x)BDASTART + tBIOSDA。 % + x

现在上面的代码可以写成:

mov ax,BDA(COM1addr)

mov bx,BDA(COM2addr)

使用这个特性,我们可以简化引用大量的宏(反过来,减少打字错误)。

% undef

命令。 例如,下列顺序:

%定义foo酒吧

% undef foo

 

mov eax,foo

不再是定义。

宏,否则是预定义的定义可以在命令行上使用- u”选项Yasm命令行:明白了 

%分配

)。

处理指令。

可以界定之后,你可以做吗

%分配我+ 1

增量的数值宏。

一个这样的例子。

),还必须评估一个纯粹的数量(而不是一个浮动参考如代码或数据地址,或任何涉及注册)。

4.2。 字符串处理在宏

通常是有用的在宏能够处理字符串。 NASM支持两个简单的字符串处理宏观运营商可以构造更复杂的操作。

% strlen

数值是一个字符串的长度。 使用的一个例子是:

% strlen charcnt '我的字符串

是一个文字字符串,但它也可以是一个单行的宏,它扩大到一个字符串,如以下示例:

%定义sometext“我的字符串”

% strlen charcnt sometext

被分配的值8。

%的子串

。 其使用的一个例子可能是更有用的描述:

% substr mychar“xyz”1;相当于%定义mychar“x”

% substr mychar“xyz”2;相当于%定义mychar‘y’

% substr mychar“xyz”3;相当于%定义mychar ' z '

),第一个参数是要创建的单行的宏,第二个是字符串。 第三个参数指定要选择哪个角色。 注意,第一个指数是1,而不是0,最后指数等于价值 % strlen 将分配给相同的字符串。 索引值的范围导致一个空字符串。

4.3。 多行宏

多行宏更像的一种宏观MASM和TASM:实现一个多行宏定义在NASM中看起来是这样的。

%宏观前言1

 

推动ebp

mov ebp,特别是

子esp,% 1

 

% endmacro

这个定义了一个c函数序言作为一个宏:所以你会调用宏的调用等

myfunc:序言12

这将扩大到三行代码

myfunc:推动ebp

mov ebp,特别是

子esp,12

等等。

多行宏,单行的宏,等 

多行宏的参数,你可以通过将整个参数包含在括号。 所以你可以代码之类的东西

%宏观傻2

 

% 2:db % 1

 

% endmacro

 

愚蠢的“a”,letter_a;letter_a:db ' a '

愚蠢的“ab”string_ab;string_ab:db“ab”

愚蠢的{ 13日10 },crlf;crlf:10 db 13日

4.3.1。 重载多行宏

与单行的宏,可以重载多行宏定义相同的宏名多次与不同数量的参数。 这一次,不例外是为宏不带参数。 所以你可以定义

%宏观序言0

 

推动ebp

mov ebp,特别是

 

% endmacro

定义函数的另一种形式的序幕分配没有本地堆栈空间。

但是,有时候您可能想要“超负荷”机器指令;例如,您可能需要定义

%宏观推2

 

推动% 1

推动% 2

 

% endmacro

这样你可以代码

推动ebx;这一行不是一个宏调用

推动eax,连成一片,但是这个是

)。

4.3.2。 Macro-Local标签

国旗由这样做:

%宏观retz 0

 

jnz % %跳过

受潮湿腐烂

% %跳过:

 

% endmacro

。 你应该避免这种形式(定义自己的标签 . . @ 前缀,然后一个数字,然后另一个时期),以防他们干扰macro-local标签。

4.3.3。 贪婪的宏参数

有时是有用的定义一个宏块整个命令行成一个参数定义,可能后提取一个或两个小参数的前面。 一个例子可能是一个宏来编写一个文本字符串在ms - dos文件,您可能希望能够编写

writefile(文件句柄),“你好,世界”,13日10

,也就是说,如果您调用宏比预计更多的参数,定义的所有多余的参数集总进入最后一个逗号分开。 所以如果你代码:

%宏writefile 2 +

 

jmp % % endstr

% % str:db % 2

% % endstr:

mov dx,% % str

mov残雪,% % endstr - % % str

mov bx,% 1

mov啊,0 x40

int 0 x21

 

% endmacro

线。

采取4参数(例如)。

当然,上面的宏可以被实现为一个贪婪的宏,在这种情况下,它必须看起来像

writefile(文件句柄),{ 10 }“hello,world”,13日

NASM提供机制(宏观参数)(逗号),你选择哪一个你更喜欢每个宏定义。

看到 有一种更好的方法来写上面的宏。

4.3.4。 默认宏参数

省略参数。 举个例子:

%宏观死0 - 1”痛苦的程序死亡发生。”

 

writefile 2,% 1

x4c01 mov ax,0

int 0 x21

 

% endmacro

)可以被称为一个显式的错误消息,它将显示在退出前错误输出流,也可以不带参数调用,在这种情况下,将使用默认错误消息中提供的宏定义。

一般来说,你提供一个最小和最大数量的这种类型的宏参数;所需的最小数量的参数然后在宏调用,然后你提供可选的默认值。 所以如果一个宏定义开始

% 1 - 3宏观foobar eax,(ebx + 2)

)允许您确定真的有多少参数传递给宏调用。

宏观上可以更强大和更有用,通过改变的第一行定义

%宏观死0 - 1 +“痛苦的程序死亡发生。”,13日10

柜台:宏参数

:旋转宏参数

不再可用。

在不丢失参数:参数旋转的左端参数列表出现在右边,反之亦然。

是负的,宏观参数向右旋转。

所以一双宏的保存和恢复的一组寄存器可能工作如下:

%宏观multipush 1 - *

 

%代表% 0

推动% 1

%旋转1

% endrep

 

% endmacro

)导致每个参数反过来推动。

宏。

,宏会照顾弹出注册以相反的顺序从一个推动。

这可以通过以下定义:

%宏观multipop 1 - *

 

%代表% 0

%旋转1

流行% 1

% endrep

 

% endmacro

。 因此,参数在相反的顺序遍历。

4.3.7。 连接宏参数

NASM可以连接宏观参数对其他文本周围。 这允许您声明一个家族的象征,例如,在一个宏定义。 例如,如果你想生成一个表的键码连同补偿到表中,你可以类似的代码

%宏观keytab_entry 2

 

keypos % 1装备keytab美元

db % 2

 

% endmacro

 

keytab:

keytab_entry F1,128 + 1

keytab_entry F2,128 + 2

keytab_entry回报,13

这将扩大到

keytab:

keytab美元keyposF1装备

db 128 + 1

keytab美元keyposF2装备

db 128 + 2

keytab美元keyposReturn装备

db 13

(给宏观参数的数量)从第二(文字文本连接到参数)。

这个连接也可以应用于其他预处理内联对象,如macro-local标签( )。 在所有情况下,语法歧义可以解决封闭后的一切 % 标志和文字文本前括号: % { % foo }酒吧 连接的文本 酒吧 到最后的真实姓名macro-local标签 % % foo 。 (这是不必要的,因为形式NASM使用真实姓名的macro-local标签意味着两种用法% { % foo }酒吧 和 % % foobar 既能扩大到相同的;然而,能力就在那里。)

为4.3.8。 码作为宏观参数条件

一个有效的状态码。

conditional-return宏:

宏观retc % 1

 

j % -1% %跳过

受潮湿腐烂

% %跳过:

 

% endmacro

将报告一个错误如果通过这些,因为不存在逆状态码。

4.3.9。 禁用清单扩张

NASM时生成一个清单文件从您的程序中,它通常会扩大通过编写多行宏宏调用清单的每一行,然后扩张。 这允许您看到宏扩展指令的生成代码;然而,对于一些宏这不必要的杂波的清单。

限定符直接参数的数量后,像这样:

% 1. nolist宏观foo

或者像这样:

1 - 5 + %宏观酒吧。 nolist a,b,c,d,e,f,g,h

4.4。 有条件的组装

类似于C预处理器,NASM允许组装部分的源文件只有在某些条件得到满足。 这个特性的一般语法看起来像这样:

%如果<条件>

;一些代码只出现> <条件是否满足

% elif < condition2 >

,只有出现如果不满足<条件> < condition2 >是

其他的%

;这似乎如果<条件>和< condition2 >了

% endif

条款。

:测试单行的宏观的存在

块(如果有的话)会被处理。

例如,当调试一个程序,您可能想要编写代码等

,执行一些功能

% ifdef调试

writefile 2,“函数执行成功”,13日10

% endif

,去做别的事情

创建一个版本的程序产生调试信息,和删除选项来生成最终的发布版本的程序。

:测试多行宏观的存在

指令,除了它检查的存在多行宏。

例如,你可能使用一个大型项目,没有控制宏在图书馆。 您可能想要创建一个宏,一个名字,如果它不存在,如果一个人与另一个名字,名字确实存在。

被认为是真实的如果定义一个宏的名称和数量的参数会导致定义冲突。 例如:

% ifmacro MyMacro 1 - 3

 

%的错误“MyMacro 1 - 3”与现有的宏观引起冲突。

 

其他的%

 

%宏观MyMacro 1 - 3

 

;插入代码来定义宏

 

% endmacro

 

% endif

如果没有宏已经存在的冲突,并发出警告是否有定义冲突。

:测试上下文堆栈

也支持。

上下文堆栈的更多细节,请参阅 

:测试任意数值表达式

给一个详细的例子。

)。

例如,返回1如果一个输入为零,否则和0)。 关系运算符也为真,0为假返回1。

:测试具体文本的身份

扩大后,单行的宏,是相同的文本。 空白的差异并不算。

不区分大小写的。

作为一个真正的注册:

宏观pushparam % 1

 

% ifidni % 1,ip

调用% %标签

% %标签:

其他的%

推动% 1

% endif

 

% endmacro

:测试令牌类型

一些宏需要执行不同的任务取决于他们是否通过一个数字,一个字符串,或一个标识符。 例如,一个字符串输出宏可能希望能够应付传递一个字符串常量或现有的字符串的指针。

测试是一个字符串。

可以扩展到利用吗 % ifstr 在以下方式:

%宏观writefile 2 - 3 +

 

% ifstr % 2

jmp % % endstr

% % 0 = 3

% % str:db % 2,% 3

其他的%

% % str:db % 2

% endif

% % % % endstr:mov dx,str

mov残雪,% % endstr - % % str

其他的%

mov dx,% 2

mov残雪,% 3

% endif

mov bx,% 1

mov啊,0 x40

int 0 x21

 

% endmacro

宏可以应对被称为在以下两个方面:

strpointer writefile(文件),长度

writefile(文件),“你好”,13日10

作为它的长度;第二,给出一个字符串宏,因此说它本身和工作地址和长度。

需要)。

:用户定义的错误报告

将导致NASM报告一个错误如果它发生在组装代码。 如果其他用户是要组装你的源文件,您可以确保他们正确的宏定义的代码是这样的:

% ifdef SOME_MACRO

,做一些设置

% elifdef SOME_OTHER_MACRO

,做一些不同的设置

其他的%

% SOME_MACRO和SOME_OTHER_MACRO定义错误。

% endif

那么任何用户无法理解你的代码应该是组装将迅速警告他们的错误,而不必等到正在运行的程序崩溃,然后不知道出现了什么问题。

4.5。 预处理程序循环

不需要参数)可以用来封装一大块代码,然后复制多次指定的预处理:

%分配我0

%代表64

公司词表+ 2 *(我)

%分配我+ 1

% endrep

指令终止循环,像这样:

斐波那契数列:

%分配我0

%分配j 1

%代表100

%如果j > 65535

% exitrep

% endif

dw j

%分配j k + i

%分配我j

%分配j k

% endrep

 

fib_number装备(斐波那契美元)/ 2

。 这是为了防止NASM进入一个无限循环的可能性在预处理器,它(多任务和多用户系统)通常导致逐渐用尽所有的系统内存和其他应用程序开始崩溃。

4.6。 包括其他文件

指令:

%包括“macros.mac”

指令。

),在命令行上给出的顺序(Yasm命令行上的任何相对路径是相对于当前工作目录,如Yasm从何而运行)。 虽然这搜索策略不匹配传统NASM行为,它匹配的行为大多数C编译器和更好的处理相对路径名。

的形式

%如果未定义MACROS_MAC

%定义MACROS_MAC

,现在定义一些宏

% endif

将已经被定义。

)。

4.7。 上下文堆栈

宏定义。 然而,对于这样一个宏观你也希望能够嵌入这些循环。

。 您可以定义标签,是当地的一个特定的上下文堆栈。

:创建和删除背景

需要一个参数,即上下文的名称。 例如:

% foobar推

在堆栈上。 你可以有多个具有相同名称的上下文堆栈:还可以对它们进行区分。

,不需要参数,消除了上下文从上下文堆栈和破坏,以及任何与之相关的标签。

4.7.2。 Context-Local标签

上面的例子可以实现通过:

%宏观重复0

 

%将重复

% $开始:

 

% endmacro

 

%的宏,直到1

 

j % -1%美元开始

%的流行

 

% endmacro

例如,通过调用

mov残雪,字符串

重复

添加残雪,3

scasb

直到e

下面的内容,等等。

4.7.3。 Context-Local单行的宏

NASM预处理程序还允许您定义单行的宏是当地的一个特定的上下文,在同样的方式:

%定义% localmac 3美元

:重命名上下文

;但这将摧毁所有的副作用context-local与上下文相关的标签和宏只是破灭。

上下文与一个不同的名称,没有接触相关的宏和标签。 所以你可以代替破坏性的代码

%的流行

%推新名称

4.7.5。 IFs示例使用上下文堆栈:块

,实现一个IF语句块为一组宏。

%宏如果1

 

%如果推

j % -1% ifnot美元

 

% endmacro

 

%其他宏观0

 

% ifctx如果

% repl其他

jmp % $ ifend

% $ ifnot:

其他的%

%错误”预计‘如果’‘其他’”

% endif

 

% endmacro

 

%宏观endif 0

 

% ifctx如果

% $ ifnot:

%的流行

% elifctx其他

% $ ifend:

%的流行

其他的%

%错误”之前预期的“如果”或“其他”endif”

% endif

 

% endmacro

,因为它使用条件装配检查宏发行以正确的顺序(例如,不打电话 endif 之前 如果 )和问题 %的错误 如果他们不是。

一个示例使用这些宏的样子:

cmp ax,软

 

如果ae

cmp bx,残雪

 

如果ae

mov ax,残雪

其他的

mov ax,软

endif

 

其他的

cmp ax,残雪

 

如果ae

mov ax,残雪

endif

 

endif

4.8。 标准宏

空一切的预处理器指令。

大多数用户级NASM语法指令(见 。 其余的标准宏观描述。

等:Yasm版本

扩大Yasm”建立“数字,通常Subversion变更集的数字。 它应被视为显著低于子副版本,并且通常只用于区分Yasm夜间快照或预发布(如发行候选版)Yasm版本。

:文件名和行号

扩展一个数值常数输入文件中的当前行号。

和输出类似“155行:还在这里”。 您可以编写一个宏

%宏观notdeadyet 0

推动eax

mov eax,__LINE__

叫stillhere

流行eax

% endmacro

直到你找到崩溃点。

关键字:输出对象格式

是调用 - f精灵 , __YASM_OBJFMT__ 扩大到 精灵 。

第二两种情况。

:声明结构数据类型

用于定义一个结构数据类型。

完成的定义。

包含longword,一句话,一个字节字符串的字节,你可能的代码

struc mytype

mt_long:resd 1

mt_word:resw 1

mt_byte:resb 1

mt_str:resb 32

endstruc

自己是零。

结构类型名称的原因是定义为零的副作用使结构与当地的标签机制:如果你的结构成员倾向于在一个以上的结构相同的名称,您可以定义上面的结构是这样的:

struc mytype

。 长:resd 1

。 词:resw 1

。 字节:resb 1

。 str:resb 32

endstruc

:声明实例的结构

在项目中,您的代码是这样的:

mystruc:istruc mytype

123456年在mt_long,dd

在mt_word dw 1024

在db mt_byte“x”

在mt_str,db“hello,world”,13日10 0

iend

前缀进装配位置的正确点指定结构字段,然后宣布指定的数据。 因此结构字段必须声明中指定的顺序在同一结构的定义。

线。 例如:

123134145156167178189年在mt_str,db

190100 db,0

结构领域完全一致,并开始下一行:

在mt_str

db“hello,world”

10 db 13日,0

:数据对齐

宏是

4,对齐4字节边界对齐

对齐16;16字节边界对齐

nop对齐16日,相当于前一行

对齐8,db 0;垫0而不是空操作

4,对齐resb 1;BSS对齐到4

alignb 4,相当于前一行

第二个参数来执行对齐前缀。

在BSS部分,不需要第二个参数除了特殊用途。

,简单的宏,执行没有错误检查:他们不能提醒你如果第一个参数不能是2的幂,或者如果他们的第二个参数生成多个字节的代码。 在每一种情况下,他们会静静地做错误的事情。

)可以使用在结构定义:

struc mytype2

mt_byte:resb 1

alignb 2

mt_word:resw 1

alignb 4

mt_long:resd 1

mt_str:resb 32

endstruc

这将确保成员结构合理对齐相对于结构的基础。

调整部分对齐最大指定对齐。

第五章。 NASM汇编指令

表的内容

5.1。 指定目标处理器模式

USE64

:改变汇编的违约

5.3。 改变和定义部分

5.3.2。 标准化的部分名称

:定义绝对标签

:导入符号

:输出符号

:定义常见的数据区域

CPU:定义依赖关系

指令。 这些都是本章中描述。

指令。 通常,每个指令都有一个用户级表单和一个基本形式。 在几乎所有情况下,我们建议用户使用用户级形式的指令,这被实现为宏调用原始的形式。

原始的指令包含在方括号;用户级指令。

5.1。 指定目标处理器模式

指令再次不必要的。

设备驱动程序和引导加载程序软件。

使用64位指令和寄存器;这样做是为了让这些指令的使用和在32位或16位程序注册名字,尽管这样的使用将会产生一个警告。

模式,反过来也是如此:32位指令不需要前缀,而指令使用16位数据需要一个0 x66这些工作需要一个0 x67 16位地址。

模式中,32位指令通常不需要前缀,大多数使用64位的寄存器或数据大小需要雷克斯前缀。 在必要时Yasm自动插入雷克斯前缀。 还有8更普遍和SSE寄存器,并不再支持16位寻址。 默认的地址大小是64位,32位寻址可以选择0 x67前缀。 默认操作数的大小仍然是32位,然而,0 x66前缀选择16位操作数的大小。 雷克斯前缀可以用来选择64位操作数的大小,并访问新的寄存器。 几条指令有一个默认的64位操作数的大小。

分别,但只有当雷克斯使用前缀。

。 用户级以外的形式是一个没有宏观功能调用原始的形式。

USE64

分别为兼容其他装配工。

:改变汇编的违约

指令改变了汇编程序默认值。 通常,Yasm默认模式,预计程序员显式地指定最直接的特性。 然而,有时这是不可取的,如果某种行为非常commmonly使用。

使用部分覆盖,或另一个注册是有效地址的一部分。

总是有基地址0,所以RIP-relative访问仍然是有意义的。

5.3。 改变和定义部分

有时可能会给一个错误消息,也可能定义一个新的部分,如果你想切换到(还)不存在的部分。

5.3.2。 标准化的部分名称

相比之下,格式不承认这些部分名称是特殊的,甚至会剥的主要时期的任何部分的名字有一个。

指令它问题,然后问题。 因此,用户级指令

部分。

扩大到两行

%定义__SECT__(部分。text)

(部分。text)

NASM手册中定义的宏可以有效地重写在接下来的更复杂的形式:

%宏writefile 2 +

(. data部分)

% % str:db % 2

% % endstr:

__SECT__

mov dx,% % str

mov残雪,% % endstr - % % str

mov bx,% 1

mov啊,0 x40

int 0 x21

% endmacro

格式模块,用户可能组装几个独立的代码的代码的任何部分。

:定义绝对标签

家庭。

使用如下:

绝对0 x1a

kbuf_chr resw 1

kbuf_free resw 1

kbuf resw 16

0 x1e。

宏调用时。

)。

),它可以是一个值在一个段。 例如,TSR可以重用的设置代码运行时BSS是这样的:

org 100 h;它是一个。 COM程序

jmp设置,设置代码

,居民TSR是这里的一部分

设置:,现在写的代码安装临时避难所

绝对的设置

runtimevar1 resw 1

runtimevar2 resd 20

tsr_end:

这定义了一些变量“之上”的设置代码,这样设置后运行结束之后,它拿起可以重用为数据存储空间的临时避难所。 象征“tsr_end”可以用来计算的总大小的一部分需要居民的临时避难所。

:导入符号

格式不能。

你喜欢的指令需要尽可能多的参数。 每一个参数是一个符号的名称:

走读生_printf

走读生_sscanf,_fscanf

通过指令

走读生_variable:关于dgroup

不同于用户级形式只有在它一次只能带一个参数:支持多种参数预处理器级别的实现。

不过,还有别的东西。

:输出符号

为这个目的。

符号的定义。

指令。 例如:

全球_main

_main:;一些代码

对象格式,例如,允许您指定全球数据项是否函数或数据:

全球hashlookup:函数,散列表:数据

不同于用户级形式只有在它一次只能带一个参数。

:定义常见的数据区域

。 常见的变量就像uninitialised数据部分中声明一个全局变量,所以

常见intvar 4

相似的函数吗

全球intvar

部分.bss

intvar resd 1

在所有模块都指向同一块内存。

格式允许您指定的对齐要求一个共同的变量:

常见commvar 4:附近;在OBJ工作

常见intarray 100:4;在精灵:4字节对齐

不同于用户级形式只有在它一次只能带一个参数。

CPU:定义依赖关系

为 CPU 选择不同的架构。

所有选择都不区分大小写。 说明将使只有适用于选定的cpu或更低。

第三部分。 气体的语法

本书的章节在这部分文档GNU兼容语法接受Yasm“气”解析器。

表的内容

6。 TBD

第六章。TBD

写的。

第四部分。 对象的格式

书的这一部分文档中的章节Yasm对各种对象文件格式的支持。

:平面形式的二进制输出

快闪记忆体)。

获取详细信息。 唯一限制这些部分是输出文件的存储位置不能重叠。

指令分别是必需的。

起源:二进制

在默认情况下使用。

获取详细信息。

指令。

指令

)指令允许复杂的排序段的输出文件或初始加载地址(也称为LMA)和最终的执行地址(虚拟地址或VMA)。

的 加载,以及它的位置在输出文件中。

通常,VMA LMA一样。 然而,他们可能会有所不同,如果程序或另一段代码副本(凡)执行前一节。 在嵌入式系统中一个典型的例子是一段代码存储在ROM中,但快复制到RAM之前执行。 另一个例子是覆盖:部分加载到不同的文件位置的需求相同的执行位置。

部分属性

属性

显示部分

progbits

存储在磁盘映像,而在负荷分配和初始化。

nobits

分配和初始化加载(progbits相反)。 指定的progbits或nobits可能只有一个,他们是相互排斥的属性。

地址

不符合一致性约束。

sectname

在输出文件中(LMA)。 如果LMA一致性约束,它是受人尊敬和插入一个缺口,部分满足一致性要求。 注意,LMA重叠是不允许的,通常只有一个部分可能遵循另一个。

n

必须是2的幂。 如果未指定LMA对齐默认为4。

地址

不符合一致性约束。

sectname

在输出文件中(VMA)。 如果VMA一致性约束,这是尊重和插入一个缺口,部分满足一致性要求。 VMA允许重叠,所以多个部分可能遵循另一个(可能是有用的在覆盖的情况下)。

n

必须是2的幂。 影响规律排列LMA对齐,如果未指定默认值。

 

指令与属性。

除非另有说明,Yasm默认设置VMA LMA =。 如果指定只是“valign,Yasm需要LMA和对齐到所需的对齐。 这可能推动下面的影响“VMAs non-LMA地址,以避免VMA重叠。

部分属性。

特殊的符号

符号:

.start

.vstart

长处

。 长度被认为是运行时,因此“nobits部分”长度是他们的运行时,而不是0。

7.4。 映射文件

指令。 如果要求但没有地图输出文件名,地图默认输出到标准输出。

指令接收以下选项来控制映射文件中包含什么内容。 可以指定多个选项。 以外的任何选项,下面是解释为输出文件名。

短暂的

值),做一个简要的介绍总结清单VMA和LMA启动和停止地址和每个部分的部分长度。

包括一个章节的详细清单,包括VMA和LMA对齐,任何“跟随”设置,以及VMA和LMA的部分开始地址和长度。

符号

包括一个详细清单的所有装备的价值观和VMA和LMA符号位置,按截面分组。

所有

所有的上面。

:通用对象文件格式

:可执行文件和可链接32位对象文件格式

表的内容

9.1。 调试格式支持

9.2。 精灵的部分

9.3。 精灵的指示

:添加文件识别

:设置符号大小

:设置符号类型

:创建软弱的象征

指令

指令

关于

FreeBSD和GNU / Linux。 它出现在三种形式:

  • 共享对象文件(所以)
  • 浮动对象文件(. o)
  • 可执行文件(没有约定)

,是一个32位精灵文件,支持64位执行(指令和寄存器),而限制指针大小为32位。

对象的格式。

9.1。 调试格式支持

)。 不同的调试器理解这些不同的格式,更新的调试格式 dwarf2 ,所以先试试。

9.2。 精灵的部分

属性

显示部分

alloc

在运行时被加载到内存中。 这是对代码和数据部分,假为元数据部分。

执行

已经许可运行可执行代码。

在运行时是可写的。

progbits

存储在磁盘映像,而在负荷分配和初始化。

n

必须是2的幂。

 

标准的主要部分属性默认值根据其预期使用,和任何未知的部分都有自己的默认值,如图所示 

部分

alloc

执行

progbits

对齐

.bss

alloc

 

 

4

. data

alloc

 

progbits

4

.rodata

alloc

   

progbits

4

。text

alloc

执行

 

progbits

16

.comment

     

progbits

0

未知的

alloc

   

progbits

1

 

9.3。 精灵的指示

:添加文件识别

大多数Unix系统上发现的命令。

节源文件中给出的顺序。

,所以它必须用方括号。 示例使用在NASM中语法:

(识别“Id”美元)

:设置符号大小

指令可以指定任何符号的大小,包括当地的象征。

指令接受两个参数,第一个参数是符号的名称,和第二个是大小。 可能是一个常量或表达式。 例子:

函数:

受潮湿腐烂

指标:最终

大小func func.end-func

:设置符号类型

指令允许指定任何符号的符号类型,包括当地的符号。

。 一个无法识别的类型会导致生成一个警告。 使用的例子:

函数:

受潮湿腐烂

类型函数函数

. data部分

var dd 4

类型变量对象

:创建软弱的象征

精灵允许某些符号定义为“软弱”。 弱符号类似于全局符号,除了在链接,弱符号只选择在全球和地方在符号解析符号。 与全球符号,多个目标文件可能声明相同的弱符号,并引用符号得到解决与弱符号只有在没有全局或局部符号有相同的名字。

libpthread,那么链接将链接“读”调用libpthread象征,忽略libc的弱者,不管库链接订单。 如果使用libc non-weak名称,“读”功能程序最终可能取决于各种各样的因素;软弱的象征是一种告诉链接器符号是resolution-wise那么重要。

指令需要一个参数,宣布弱符号名称。 例子:

weakfunc:

strongfunc:

受潮湿腐烂

弱weakfunc

全球strongfunc

指令

允许指定该信息非全局符号。

)。 例如:

全球hashlookup:函数,散列表:数据

作为一个数据对象。

隐藏:

全球hashlookup:隐藏功能

您还可以指定与符号相关的数据的大小,作为一个数值表达式(可能涉及到标签,甚至向前引用)在类型说明符。 是这样的:

全球散列表:数据(散列表。 结束-散列表)

 

散列表:

db,一次;一些数据

指标:最终

)指令如下:

全球散列表

哈希表对象类型

大小hashtable hashtable。 ——散列表

 

散列表:

db,一次;一些数据

指标:最终

声明全局符号的类型和尺寸是必要的写作时共享库代码。

指令

精灵也允许您指定对齐要求共同的变量。 这是通过把数量(必须是2的幂)共同的变量的名称和大小后,(像往常一样)用冒号分开。 例如,一个双字将受益于4字节对齐的数组:

常见dwordarray 128:4

这个声明数组的总大小是128字节,并要求将其在一个4字节边界对齐。

关于

ELF规范包含足够的特性允许位置无关代码编写(PIC),这使得精灵共享库非常灵活。 然而,这也意味着Yasm必须能够生成各种奇怪的迁移类型在ELF对象文件中,如果它是一个可以编写汇编程序 照片。

不同的目的,即PIC-specific搬迁类型。

。 它们的功能进行了总结:

. . gotpc

指的是符号标记 结果得到的真实地址。

. . gotoff

会给的距离到达指定位置,以便增加的地址有会给你想要的真正的地址位置。

. .了

的包含了地址的象征,并参考了距离的开始要进入,所以您可以添加的地址,负载产生的地址和最终的地址的象征。

. . plt

),因为精灵不包含搬迁绝对引用PLT条目类型。

.信谊

导致Yasm写一个普通的搬迁,而是让搬迁相对于部分的开始,然后添加偏移量的符号,它将编写一个搬迁记录直接针对问题的象征。 的区别是一个必要的动态链接器的特点。

:可执行文件和可链接格式64位对象文件

表的内容

关于

对象的格式。

)推荐的调试格式。

额外的指令精灵提供细节。

关于

相对寻址,大多数变量访问可以相对于RIP,允许简单的共享库的搬迁到不同的内存地址。

PIC-specific搬迁类型。

。 它们的功能进行了总结:

. . gotpcrel

有大小可以通过这种方法仅限于2 GB。

. .了

的包含了地址的象征,并参考了距离的开始要进入,所以您可以添加的地址,负载产生的地址和最终的地址的象征。

. . plt

),因为精灵不包含搬迁绝对引用PLT条目类型。

.信谊

导致Yasm写一个普通的搬迁,而是让搬迁相对于部分的开始,然后添加偏移量的符号,它将编写一个搬迁记录直接针对问题的象征。 的区别是一个必要的动态链接器的特点。

:精灵32位64位处理器对象文件

表的内容

关于

。 操作系统支持 elfx32 目前常见的比 elf64 。

对象的格式。

额外的指令精灵提供细节。

关于

。 它们的功能进行了总结:

. . gotpcrel

有大小可以通过这种方法仅限于2 GB。

. .了

的包含了地址的象征,并参考了距离的开始要进入,所以您可以添加的地址,负载产生的地址和最终的地址的象征。

. . plt

),因为精灵不包含搬迁绝对引用PLT条目类型。

.信谊

导致Yasm写一个普通的搬迁,而是让搬迁相对于部分的开始,然后添加偏移量的符号,它将编写一个搬迁记录直接针对问题的象征。 的区别是一个必要的动态链接器的特点。

:32位马赫对象文件格式

:马赫64位对象文件格式

:浮动动态对象文件格式

:微软Win32对象文件

表的内容

指令

:安全结构化异常处理

PE可执行文件。

格式不产生目标文件,Win32连接器能产生正确的输出。

指令

,但仍有可能被这些限定符。

可用的限定符是:

文本

定义了部分代码部分。 这标志着部分可读和可执行文件,但没有可写的,还指示链接器,部分代码的类型。

bss

声明了一个未初始化的数据部分。

rdata

声明了一个初始化数据段是可读的,但没有可写的。 微软编译器使用本节将常数。

信息

定义的部分 导致连接器部分的内容解释为命令行选项。

n

指定的对齐需求部分。 您可以指定的最高分数为8192:Win32对象文件格式包含不要求更大的部分对齐。 如果没有显式地指定对齐,默认值是16字节对齐的代码部分,8字节对齐rdata部分和4字节对齐的数据(BSS)部分。 信息部分的默认对齐方式1字节(没有对齐),虽然价值并不重要。 的定位必须是2的幂。

清除丢弃标志。

默认值由Yasm如果不指定上述限定符是:

部分。 对齐文本代码= 16

部分。 数据数据对齐= 4

部分。 rdata rdata对齐= 8

部分。 rodata rdata对齐= 8

部分。 rdata rdata对齐= 8美元

部分。 bss bss对齐= 4

部分。 drectve信息

部分.comment信息

:安全结构化异常处理

命令行选项。

例子

部分。

走读生_MessageBoxA@16

safeseh处理程序,处理程序注册为“安全处理程序”

处理程序:

推动DWORD 1;MB_OKCANCEL

把字标题

推动DWORD文本

把字0

叫_MessageBoxA@16

子eax,1;顺便说一句适合作为返回值

,因为异常处理程序

受潮湿腐烂

全球_main

_main:

把字处理程序

推动DWORD[fs:0]

mov DWORD[fs:0],esp;异常处理程序

xor eax,eax

mov eax,DWORD[eax];导致异常

字流行[fs:0];解除异常处理程序

添加esp,4

受潮湿腐烂

文本:db”可以重新抛出,取消生成核心转储”,0

标题:db SEGV,0

 

部分。 drectve信息

db / defaultlib:user32。 lib / defaultlib:msvcrt。 自由的

 

指令。

符号和数据安全的异常处理程序表因为没有向后不兼容,因此“safeseh”生成对象文件仍然可以由链接器版本或非微软早些时候连接器连接起来。

:PE32 +(微软Win64)对象文件

表的内容

指令

结构化异常处理

16.2.1。 约定x64堆栈、寄存器和功能参数

16.2.2。 类型的函数

16.2.3。 框架功能结构

16.2.4。 堆栈框架的细节

16.2.5。 Yasm为解除操作原语

16.2.6。 Yasm宏正式栈操作

PE32 +可执行文件。

指令

指令,控制部分声明的类型和属性。

结构化异常处理

大多数函数,利用堆栈的64位版本的Windows必须支持异常处理,即使他们没有内部使用的设施。 这是因为这些操作系统定位异常处理程序通过使用这一过程被称为“栈”,取决于功能提供数据,描述了他们如何使用堆栈。

当发生异常栈是“解除”工作向后通过函数调用链异常事件前确定功能是否具有适当的异常处理程序或他们是否有保存的非易失性寄存器的值需要恢复为了重建的执行上下文中的下一个更高的功能链。 这个过程取决于编译器和汇编程序提供“解除数据”功能。

以下部分详述的机制可用Yasm满足这些需求,从而允许函数写在汇编程序中使用的编码惯例遵守64位版本的Windows。 这些Yasm MASM。实现中提供设备遵循这些

16.2.1。 约定x64堆栈、寄存器和功能参数

图16.1 显示了如何在函数调用栈通常使用。 当一个函数被调用时,一个8字节的返回地址是自动推到堆栈和函数然后保存它将使用的任何非易失性寄存器。 额外的空间也可以分配给本地变量和一个帧指针寄存器可以被指定。

用户手册是Yasm汇编

 

前四个整数函数参数传递(从左到右顺序)寄存器RCX,RDX,R8和R9机型。 进一步的整数参数传递到栈上推在右到左的顺序(向左参数在低地址)。 栈空间是分配给四个寄存器参数(“影子空间”),但他们的价值观并不存储由调用函数调用的函数必须这样做,如果必要的。 调用函数有效地拥有这个空间,可以使用它为任何目的,因此,在返回调用函数不能依靠其内容。 注册参数占据最低有效位的寄存器和影子空间必须分配给四个寄存器参数,即使被调用的函数没有这么多参数。

前四个浮点参数传入XMM0 XMM3。 当混合整数和浮点参数时,参数和寄存器之间的通信是没有改变。 因此一个整数参数在两个浮点的R8 RCX和RDX未使用。

当它们通过值,结构和工会的尺寸8,16、32或64位传递相同大小的整数。 数组和更大的结构和工会作为指针传递给调用函数的内存分配和分配。

寄存器伸展,RCX,RDX、R8 R9机型,R10,R11是挥发性的,可以自由使用的调用函数没有保存它们的值(但是请注意,一些可用于传递参数)。 由于功能不能指望这些寄存器保存调用其他函数。

寄存器RBX RBP,肢体重复性劳损症,RDI R12,R13,R14、R15和XMM6 XMM15非易失性,必须保存和恢复功能,使用它们。

除了浮点值,返回XMM0,函数返回值,适合在递交的64位返回。 一些128位值也传入XMM0但较大的值返回调用程序在内存中分配的,并指出通过一个额外的“隐藏”函数参数,成为第一个参数和推动其他参数。 这个指针值也必须返回给调用程序在调用的程序返回时递交。

16.2.2。 类型的函数

函数分配堆栈空间,调用其他函数,非易失性寄存器保存或使用异常处理被称为“帧函数”;其他功能被称为“叶功能”。

帧函数使用一个区域在堆栈上称为“堆栈帧”和有一个定义的序言中设置。 通常他们在影子的位置保存寄存器参数(如果需要的话),他们使用的任何非易失性寄存器保存,为局部变量分配堆栈空间,并建立一个注册为一个堆栈帧指针。 他们还必须有一个或多个定义的尾声,免费的任何分配堆栈空间和恢复非易失性寄存器之前返回到调用函数。

除非动态分配堆栈空间,一个框架函数必须保持16字节对齐的堆栈指针,同时在其序言和后记外代码(在调用其他函数除外)。 一帧函数动态地分配堆栈空间必须首先需要分配任何固定的堆栈空间,然后分配和建立一个索引寄存器访问该地区。 这个区域的较低的基地址必须是16字节对齐的,必须提供注册而不管函数本身使得显式地使用它。 然后自由离开函数堆栈对齐在执行期间虽然必须重建16字节对齐如果或当它调用其他函数。

叶功能不需要定义序言或后记但他们不能调用其他函数;也不能改变任何非易失性寄存器和堆栈指针(这意味着他们不保持16字节的堆栈对齐在执行期间)。 不过,它们可以退出,跳转到另一个框架或叶的入口点函数提供了相应的堆参数是兼容的。

总结了这些规则 (函数的代码不属于序言或后记中提到表函数的身体)。

功能需求或可以:

帧与帧指针寄存器函数

框架没有帧指针寄存器函数

叶函数

序言和后记(s)

是的

是的

没有

使用异常处理

是的

是的

没有

到栈上分配空间

是的

是的

没有

保存或寄存器推压入堆栈

是的

是的

没有

使用非易失性寄存器(在保存)

是的

是的

没有

使用动态堆栈分配

是的

没有

没有

在函数体改变堆栈指针

]

没有

没有

在函数体对齐堆栈指针

]

没有

是的

打电话给其他函数

是的

是的

没有

使跳到其他功能

没有

没有

]

但16字节的堆栈对齐时,必须重新建立任何函数调用。

但是寄存器和堆栈的函数参数必须一致。

 

16.2.3。 框架功能结构

已经表明,帧函数必须有一个良好定义的结构包括序言和一个或多个尾声,每个特定的形式。 一个函数中的代码不属于它的序言或其一个或多个结语将把这里称为函数的身体。

一个典型的功能序言的形式:

mov负责+ 8,rcx,参数存储在影子空间如果有必要

推动r14;保存任何要使用非易失性寄存器

推动r13;

子负责,大小;如果需要为局部变量分配堆栈

lea r13[偏差+负责];用r13帧指针偏移

当一个帧指针需要程序员可以选择使用哪个寄存器(“偏见”将在稍后解释)。 虽然它没有用于访问分配空间,它必须分配在序言和执行期间保持不变的主体功能。

大小在递交之前分配堆栈空间为了如果需要内存页添加到堆栈(参见微软Visual Studio 2005文档详情)。

匹配的结语是:

lea负责,r13-bias;这不是官方后记的一部分

添加负责,大小;官方结语从这里开始

流行r13

流行r14

受潮湿腐烂

也可以使用以下规定,已经建立了一个帧指针寄存器:

lea负责,[r13 + size-bias]

流行r13

流行r14

受潮湿腐烂

;第一个表单可以使用有或没有一个帧指针寄存器但第二种形式要求。 这些指令然后其次是零个或多个8字节寄存器持久性有机污染物和返回指令(可替换为一组有限的跳转指令如微软文档中所述)。 结语形式高度受限,因为这允许例外调度代码来定位他们不需要解除数据除了提供序言。

每个函数的位置和数据长度的序幕,在任何固定堆栈分配和任何非易失性寄存器保存在对象代码是记录在特殊的部分。 Yasm提供宏创建这些数据,现在将描述(例子的方式使用它们)。

16.2.4。 堆栈框架的细节

有两种类型的堆栈帧,在创建解除数据需要考虑。

第一,左边所示 ,仅涉及一个固定分配堆栈空间和结果的堆栈指针仍然固定在价值函数的身体除了在调用其他函数。 在这种类型的堆栈帧堆栈指针值的序言作为补偿的基础在后面描述的解除原语和宏。 它必须是16字节对齐的。

用户手册是Yasm汇编

 

第二种类型的框架,所示 栈空间是动态分配的结果,堆栈指针的值是静态预测,不能作为解除补偿。 在这种情况下必须使用帧指针寄存器提供这个基地址。 解除补偿的基础是低端的固定在堆栈上分配区域,这是通常的价值框架时的堆栈指针寄存器分配。 一定是16字节对齐,必须分配任何解除之前宏与补偿。

为了让最大数量的数据访问单个字节偏移量\ + 127(-128)从帧指针寄存器,它是正常的,以抵消其价值对分配的中心区域(之前介绍的“偏见”)。 帧指针寄存器的身份,这抵消必须16字节的倍数,记录在解除数据允许堆栈帧基地址计算帧寄存器中的值。

16.2.5。 Yasm为解除操作原语

这是低水平设施Yasm提供创建解除数据。

的名字

一个函数的结构化异常处理数据。

]

代替。

]

生成解除数据寄存器和堆栈帧偏移量。 偏移量必须16的倍数和小于或等于240。

]

生成撤销堆栈空间的数据。 尺寸必须是8的倍数。

]

生成解除指定的寄存器和数据抵消;必须积极抵消8的倍数的基础相对于过程的框架。

]

生成解除数据指定XMM寄存器和抵消;必须积极抵消16的倍数的基础相对于过程的框架。

]

生成解除40或48字节的数据(使用一个可选的错误代码)框架用于存储硬件的结果异常或中断。

(endprolog)

信号的序言,必须在第一个255字节的函数。

endproc_frame

例16.1 显示了如何使用这些原语(这是基于Microsoft Visual Studio 2005中提供一个例子文档)。

PROC_FRAME样本

db 0 x48;发出雷克斯前缀,使热修补

推动rbp;拯救未来的帧指针

[pushreg rbp];创建解除数据rbp寄存器推

子负责,0 x40;分配堆栈空间

[]allocstack 0 x40;创建解除数据堆栈分配

lea rbp,[负责+ 0 x20];分配帧指针的偏见32

[setframe rbp,0 x20);在rbp创建解除一帧数据寄存器

xmm7 movdqa(rbp),节省非易失性寄存器XMM

[savexmm128 xmm7,0 x20);创建解除XMM寄存器保存数据

mov(rbp + 0 x18),肢体重复性劳损症;保存肢体重复性劳损症

[savereg rsi,0 x38];创建解除数据保存肢体重复性劳损症

mov负责+ 0 x10,rdi;拯救rdi

(savereg rdi 0 x10);创建rdi的解除数据保存

(endprolog)

 

;我们可以改变堆栈指针之外的开场白,因为我们

,有一个帧指针。 如果我们没有一个这将是非法的。

;帧指针是必要的因为这个堆栈指针修改。

 

子负责,0 x60;我们可以自由修改堆栈指针

mov伸展,0;我们可以解除这个访问违例

mov伸展,伸展

 

movdqa xmm7(rbp);恢复寄存器没有保存

mov rsi(rbp + 0 x18);推动;这不是的一部分

mov rdi[rbp-0x10];官方跋

 

lea负责,(rbp + 0 x20),这是官方的尾声

流行rbp

受潮湿腐烂

ENDPROC_FRAME

 

16.2.6。 Yasm宏正式栈操作

从前面给出的YASM原语的描述可以看出,每个正常的堆栈操作之间有密切的关系和相关的原始需要生成其解除数据。 由于它是明智的,提供一组宏执行两个操作在一个宏调用。 Yasm提供了以下宏结合的两个操作。

的名字

n

字节。

疯狂的

在堆栈上。

注册

在堆栈上。

注册

在堆栈上使用一个2字节指令。

疯狂的

在堆栈上。

疯狂的

在堆栈上。

push_eflags

推动eflags寄存器

push_rex_eflags

推动eflags寄存器使用一个2字节指令(允许热修补)。

代码

推动一个40字节帧和一个可选的8字节错误代码压入堆栈。

end_prolog

)。

endproc_frame

使用这些更高层次的宏。

PROC_FRAME样本;开始的序幕

rex_push_reg rbp;推动未来的帧指针

alloc_stack 0 x40;分配64字节的堆栈空间

set_frame rbp,0 x20;设置一个框架注册(负责+ 32)

save_xmm128 xmm7 0 x20;节省xmm7,肢体重复性劳损症和rdi到本地堆栈空间

save_reg肢体重复性劳损症,0 x38;放松基地地址:[rsp_after_entry - 72]

save_reg rdi,0 x10;框架寄存器值:[rsp_after_entry - 40]

END_PROLOGUE

子负责,0 x60;我们现在可以改变堆栈指针

mov伸展,0;解除这个访问违例

mov伸展,伸展,因为我们有一个帧指针

 

movdqa xmm7(rbp);恢复寄存器,没救了

mov rsi(rbp + 0 x18);推动(而不是官方跋的一部分)

mov rdi[rbp-0x10]

 

lea负责(rbp + 0 x20),官方的尾声

流行rbp

受潮湿腐烂

ENDPROC_FRAME

 

:扩展动态对象的格式

第五部分。 调试格式

书的这一部分文档中的章节Yasm对各种调试格式的支持。

:VC8 CodeView调试格式

:DWARF2调试格式

:刺穿了调试格式

第六部分架构。

书的这一部分文档中的章节Yasm对各种指令集架构的支持。

21章。 x86体系结构

的 x86架构的通用名称是多供应商16位,32位,最近64位架构。 最初由英特尔的8086系列CPU,英特尔在80386年扩展到32位的CPU,并延长AMD Opteron 64位,Athlon 64 CPU。 而在2007年,英特尔和AMD是最高的x86处理器体积制造商,许多其他供应商也生产x86处理器。 通常制造商已经交换专利权(或复制)主要架构的改进,但也有一些独特的功能出现在许多的实现。

21.1。说明

x86体系结构有一个可变的指令大小,允许适度的代码压缩,同时允许非常复杂的操作数组合以及一个非常大的和许多扩展指令集的大小。 指令一般变化从零到三个操作数只有一个内存操作数允许的。

21.1.1。 NOP填充

不同的处理器有不同的建议 用于NOP(没有操作)指令 直到最近,尽管这操作码是非法。 旧处理器不支持这些专用长NOP操作码一般建议选择不再NOP序列;虽然这些序列做空操作,会导致在新处理器解码效率低下。

列出了各种组合生成的空操作。

CPU

填充

16

任何

16位短空操作

32

没有,或少于686

32位短空操作(没有长空操作)

32

686或最新的英特尔处理器

英特尔指南,使用长空操作

32

转K6或更新的AMD处理器

AMD K10指南,使用长空操作

64年

没有一个

英特尔指南,使用长空操作

64年

686或最新的英特尔处理器

英特尔指南,使用长空操作

64年

转K6或更新的AMD处理器

AMD K10指南,使用长空操作

 

此外,上述违约可能覆盖通过选项之一 到 CPU 指令。

指令选项

的名字

描述

basicnop

长时间空操作不习惯

intelnop

英特尔指南,使用长空操作

amdnop

AMD K10指南,使用长空操作

 

21.2。 执行模式和扩展

x86在许多方面已经扩展在整个历史进程中,剩下的大多是向后兼容的同时添加执行模式和大扩展指令集。现代x86处理器可以在四种主要模式:16位真正的模式中,16位保护模式,32位保护模式,和64位长模式。 的主要区别真实和保护模式的处理部分:在实模式段直接寻址内存16字节的页面,而在保护模式片段而不是索引到描述符表,其中包含的物理基础和大小。 32位保护模式允许分页和虚拟内存,以及一个32位的,而不是一个16位的偏移量。

16位和32位的操作模式都允许使用16位和32位寄存器通过设置操作和指令前缀地址大小16位或32位,与活跃的操作模式设置默认操作规模和“其他”大小被标记为一个前缀。 这些操作和地址大小也影响直接操作数的大小:例如,一个与一个32位的指令操作的大小和立即操作数将有一个32位值的编码指令,除了优化等符号扩展8位值。

相对。

21.2.1。 CPU的选择

列出了CPU名称Yasm支持。 同时拥有功能标志和CPU名称允许组合等 CPU P3 nofpu 。 特色旗帜和CPU名称不区分大小写。

的名字

描述

FPU

浮点单元(FPU)指令

MMX

MMX SIMD指令

上交所

流SIMD扩展(SSE)指令

SSE2

流SIMD指令扩展2

SSE3

流SIMD指令扩展3

SSSE3

补充流SIMD指令扩展3

SSE4.1

流SIMD扩展4,彭林子集(47个指令)

SSE4.2

流SIMD扩展4,Nehalem子集(7指令)

SSE4

所有流SIMD指令扩展4(SSE4.1和SSE4.2)

SSE4a

4流SIMD扩展(AMD)

SSE5

流SIMD扩展5

XSAVE

XSAVE指令

AVX

先进的矢量扩展指令

菲利普-马萨

延时指令

AES

高级加密标准说明

CLMUL,PCLMULQDQ

PCLMULQDQ指令

3 dnow

3 dnow ! 指令

新瑞仕

Cyrix-specific指令

AMD

比转K6 AMD-specific指令(旧)

多发性骨髓瘤

系统管理模式指令

普罗特,保护

只保护模式指令

Undoc,无证

非法指令

奥林匹克广播服务公司,过时了

过时的指令

我感到,特权

特权指令

支持向量机

安全虚拟机指令

挂锁

通过挂锁指令

EM64T

英特尔EM64T或更好的指令(不一定仅64位)

 

表21.4。 x86处理器的名字

的名字

功能标志

描述

8086年

我感到

英特尔8086年

186年,80186年,i186

我感到

英特尔80186年

286年,80286年,i286

我感到

英特尔80286年

386年,80386年,i386

多发性骨髓瘤,普罗特,我感到

英特尔80386年

486年,80486年,i486

FPU,多发性骨髓瘤,普罗特,我感到

英特尔80486年

586年,i586奔腾,P5

FPU,多发性骨髓瘤,普罗特,我感到

英特尔奔腾

686年,i686 P6、PPro PentiumPro

FPU,多发性骨髓瘤,普罗特,我感到

英特尔奔腾

P2,Pentium2、Pentium-2 PentiumII,奔腾ii

MMX,FPU,多发性骨髓瘤,普罗特,我感到

英特尔奔腾II

P3、Pentium3奔腾3、PentiumIII pentium iii,卡特迈

上交所、MMX FPU,多发性骨髓瘤,普罗特,我感到

英特尔奔腾III

P4、Pentium4奔腾4,PentiumIV Williamette奔腾iv

SSE2、SSE MMX,FPU,多发性骨髓瘤,普罗特,我感到

英特尔奔腾4

IA64,安腾ia - 64

SSE2、SSE MMX,FPU,多发性骨髓瘤,普罗特,我感到

英特尔安腾(x86)

转K6

3 dnow MMX,FPU,多发性骨髓瘤,普罗特,我感到

AMD转K6

速龙,K7

上交所,3 dnow MMX,FPU,多发性骨髓瘤,普罗特,我感到

的AMD Athlon

锤,抓奏的,皓龙处理器、Athlon64速龙- 64

SSE2、上交所、3 dnow MMX,FPU,多发性骨髓瘤,普罗特,我感到

AMD Athlon64和皓龙处理器

普莱斯考特

SSE3 SSE2,上交所MMX,FPU,多发性骨髓瘤,普罗特,我感到

英特尔代号普雷斯科特

Conroe,嵌件

SSSE3、SSE3 SSE2、SSE MMX,FPU,多发性骨髓瘤,普罗特,我感到

英特尔代号Conroe

彭林

SSE4.1、SSSE3 SSE3 SSE2,SSE,MMX,FPU,多发性骨髓瘤,普罗特,我感到

英特尔代号彭林

Nehalem,Corei7

XSAVE、SSE4.2 SSE4.1、SSSE3 SSE3,SSE2,上交所,MMX,FPU,多发性骨髓瘤,普罗特,我感到

英特尔代号Nehalem

Westmere

CLMUL,AES、XSAVE SSE4.2、SSE4.1 SSSE3,SSE3,SSE2,上交所,MMX,FPU,多发性骨髓瘤,普罗特,我感到

英特尔代号Westmere

Sandybridge

AES,AVX,CLMUL XSAVE、SSE4.2 SSE4.1,SSSE3,SSE3,SSE2,上交所,MMX,FPU,多发性骨髓瘤,普罗特,我感到

英特尔代号桑迪大桥

威尼斯

SSE3 SSE2,上交所、3 dnow MMX,FPU,多发性骨髓瘤,普罗特,我感到

AMD代号威尼斯

Family10h K10、杰出人才

SSE4a、SSE3 SSE2 SSE,3 dnow,MMX,FPU,多发性骨髓瘤,普罗特,我感到

AMD代号K10

推土机

SSE5、SSE4a SSE3 SSE2,SSE,3 dnow MMX,FPU,多发性骨髓瘤,普罗特,我感到

AMD代号推土机

 

)或定位一个64位的对象格式等 elf64 。

默认为最新的处理器CPU设置和所有特性标志启用;例如x86指令的处理器,包括所有的指令集扩展和64位指令。

21.3。寄存器

。 最初的8位和16位寄存器名称映射到最不重要的部分32位寄存器。

)。

图21.1 总结了完整的64位x86通用寄存器组。

用户手册是Yasm汇编

 

21.4。分割

指数

符号

! =, %如果:测试任意数值表达式

美元

表达式

数字常量

elf32特殊符号和关于

*、/、/ /、%和% %:乘法和除法

Context-Local标签

Context-Local标签

Macro-Local标签

*、/、/ /、%和% %:乘法和除法

连接一行宏观标记:% +

码作为宏观参数条件

码作为宏观参数条件

% 0:宏观参数计数器

预处理器变量:%分配

标准宏

正常方式:%定义

%如果:测试任意数值表达式

% ifctx:测试上下文堆栈

% ifdef:测试单行的宏观的存在

ifid百分比、ifnum百分比,% ifstr:测试令牌类型

% ifidn和% ifidni:测试具体文本的身份

% ifidn和% ifidni:测试具体文本的身份

% ifmacro:测试多行宏观的存在

% ifctx:测试上下文堆栈

% ifdef:测试单行的宏观的存在

ifid百分比、ifnum百分比,% ifstr:测试令牌类型

% ifidn和% ifidni:测试具体文本的身份

% ifidn和% ifidni:测试具体文本的身份

% ifmacro:测试多行宏观的存在

ifid百分比、ifnum百分比,% ifstr:测试令牌类型

ifid百分比、ifnum百分比,% ifstr:测试令牌类型

ifid百分比、ifnum百分比,% ifstr:测试令牌类型

ifid百分比、ifnum百分比,% ifstr:测试令牌类型

有条件的组装

预处理程序循环

%错误:用户定义的错误报告

预处理程序循环

预处理器变量:%分配

正常方式:%定义

%如果:测试任意数值表达式

IFs示例使用上下文堆栈:块

% ifdef:测试单行的宏观的存在

ifid百分比、ifnum百分比,% ifstr:测试令牌类型

% ifidn和% ifidni:测试具体文本的身份

% ifidn和% ifidni:测试具体文本的身份

% ifmacro:测试多行宏观的存在

% ifctx:测试上下文堆栈

% ifdef:测试单行的宏观的存在

ifid百分比、ifnum百分比,% ifstr:测试令牌类型

% ifidn和% ifidni:测试具体文本的身份

% ifidn和% ifidni:测试具体文本的身份

% ifmacro:测试多行宏观的存在

ifid百分比、ifnum百分比,% ifstr:测试令牌类型

ifid百分比、ifnum百分比,% ifstr:测试令牌类型

ifid百分比、ifnum百分比,% ifstr:测试令牌类型

ifid百分比、ifnum百分比,% ifstr:测试令牌类型

多行宏

包括其他文件

多行宏

%和%推流行:创建和删除背景

%和%推流行:创建和删除背景

预处理程序循环

% repl:重命名上下文

%:旋转旋转宏观参数

字符串长度:% strlen

子:%的子串

它通过宏:% undef

提高%定义:% xdefine

提高%定义:% xdefine

&:按位与运算符

%如果:测试任意数值表达式

*、/、/ /、%和% %:乘法和除法

贪婪的宏参数

+操作符

+和-:加法和减法运算符

一元运算符:+、-、~和凹陷

——操作符

+和-:加法和减法运算符

一元运算符:+、-、~和凹陷

映射文件

关键字__YASM_OBJFMT__ __OUTPUT_FORMAT__:输出对象格式

包括其他文件

Macro-Local标签

当地的标签

elfx32特殊符号和关于

elf32特殊符号和关于

elf32特殊符号和关于

elfx32特殊符号和关于

elfx32特殊符号和关于

elfx32特殊符号和关于

本:平面形式二进制输出

鉴别:添加文件识别

win32扩展部分指令

禁用清单扩张

win32:Microsoft win32对象文件

win64结构化异常处理

本:平面形式二进制输出

win64结构化异常处理

*、/、/ /、%和% %:乘法和除法

*、/、/ /、%和% %:乘法和除法

16位模式

win32:Microsoft win32对象文件

32位模式

elf32特殊符号和关于

win64:PE32 +(微软win64)对象文件

elf64特殊符号和关于

%如果:测试任意数值表达式

< <和> >:移位操作符

%如果:测试任意数值表达式

%如果:测试任意数值表达式

%如果:测试任意数值表达式

%如果:测试任意数值表达式

%如果:测试任意数值表达式

%如果:测试任意数值表达式

< <和> >:移位操作符

RESB和朋友:声明未初始化的数据

映射文件

^:按位异或运算符

%如果:测试任意数值表达式

__FILE__ __LINE__:文件名和行号

__FILE__ __LINE__:文件名和行号

关键字__YASM_OBJFMT__ __OUTPUT_FORMAT__:输出对象格式

绝对绝对:定义标签

__YASM_MAJOR__等:Yasm版本

__YASM_MAJOR__等:Yasm版本

__YASM_MAJOR__等:Yasm版本

关键字__YASM_OBJFMT__ __OUTPUT_FORMAT__:输出对象格式

__YASM_MAJOR__等:Yasm版本

__YASM_MAJOR__等:Yasm版本

__YASM_MAJOR__等:Yasm版本

|:按位或运算符

%如果:测试任意数值表达式

一元运算符:+、-、~和凹陷

一个

默认值:改变汇编违约

绝对绝对:定义标签

+和-:加法和减法运算符

NASM源代码行布局

连接宏参数

有效的地址

本指令扩展部分

NOP填充

对齐和ALIGNB:数据对齐

对齐

NOP填充

win32扩展部分指令

精灵共同扩展指令

精灵共同扩展指令

x86体系结构

NOP填充

%如果:测试任意数值表达式

多行宏

NASM汇编指令

关键表达式

ISTRUC,IEND:声明的实例的结构

B

NOP填充

本:平面形式二进制输出

+和-:加法和减法运算符

INCBIN:包括外部的二进制文件

ORG:二进制起源

< <和> >:移位操作符

&:按位与运算符

|:按位或运算符

^:按位异或运算符

IFs示例使用上下文堆栈:块

牙套

连接宏参数

多行宏

C

赛格和关于

预处理器变量:%分配

% ifidn和% ifidni:测试具体文本的身份

多行宏

改变和定义部分

DB和朋友:宣布初始化数据

字符常量

正常方式:%定义

NOP填充

VC8 cv8:CodeView调试格式

coff:通用对象文件格式

COFF

刺穿:刺穿了调试格式

NASM源代码行布局

常见的:定义常见的数据区域

coff:通用对象文件格式

常见的:定义常见的数据区域

精灵共同扩展指令

连接宏参数

码作为宏观参数条件

有条件的组装

码作为宏观参数条件

常量

浮点型常量

% ifctx:测试上下文堆栈

IFs示例使用上下文堆栈:块

Context-Local标签

Context-Local单行的宏

% 0:宏观参数计数器

CPU:定义CPU依赖性

字符常量

%和%推流行:创建和删除背景

绝对绝对:定义标签

关键表达式

VC8 cv8:CodeView调试格式

D

精灵扩展全球指令

字符串常量

浮点型常量

DB和朋友:宣布初始化数据

NASM源代码行布局

刺穿:刺穿了调试格式

STRUC ENDSTRUC:声明数据类型结构

默认值:改变汇编违约

精灵扩展全球指令

默认宏参数

改变和定义部分

精灵的指示

禁用清单扩张

*、/、/ /、%和% %:乘法和除法

DB和朋友:宣布初始化数据

浮点型常量

浮点型常量

时报》:重复指令或数据

浮点型常量

dwarf2:dwarf2调试格式

dwarf2:dwarf2调试格式

NASM源代码行布局

E

有效的地址

NASM源代码行布局

关键表达式

elf64:可执行文件和可链接格式64位对象文件

精灵的指示

elf32:可执行文件和可链接32位对象文件格式

elf64:可执行文件和可链接格式64位对象文件

elfx32:精灵32位64位处理器对象文件

精灵的部分

大小:设置符号大小

类型:设置符号类型

弱势:创建软弱的象征

精灵

elf32特殊符号和关于

elf64特殊符号和关于

刺穿:刺穿了调试格式

elfx32特殊符号和关于

elf32:可执行文件和可链接32位对象文件格式

elf64:可执行文件和可链接格式64位对象文件

elfx32:精灵32位64位处理器对象文件

绝对绝对:定义标签

关键表达式

% ifidn和% ifidni:测试具体文本的身份

elf32:可执行文件和可链接32位对象文件格式

elf64:可执行文件和可链接格式64位对象文件

elfx32:精灵32位64位处理器对象文件

全球:导出符号

表达式

xdf:扩展动态对象的格式

走读生:导入符号

F

赛格和关于

本:平面形式二进制输出

本:平面形式二进制输出

DB和朋友:宣布初始化数据

浮点型常量

本指令扩展部分

NASM汇编指令

关键表达式

elf32:可执行文件和可链接32位对象文件格式

精灵扩展全球指令

G

刺穿:刺穿了调试格式

精灵扩展全球指令

elf32特殊符号和关于

elfx32特殊符号和关于

INCBIN:包括外部的二进制文件

贪婪的宏参数

赛格和关于

H

表达式

数字常量

精灵扩展全球指令

鉴别:添加文件识别

ISTRUC,IEND:声明的实例的结构

直接操作数

走读生:导入符号

win32扩展部分指令

win32扩展部分指令

字符串常量

包括其他文件

表达式

win32扩展部分指令

DB和朋友:宣布初始化数据

ISTRUC,IEND:声明的实例的结构

浮点型常量

NOP填充

精灵扩展全球指令

ISTRUC,IEND:声明的实例的结构

%:旋转旋转宏观参数

l

当地的标签

弱势:创建软弱的象征

Linux

elf64:可执行文件和可链接格式64位对象文件

elfx32:精灵32位64位处理器对象文件

字符常量

本指令扩展部分

当地的标签

%如果:测试任意数值表达式

%如果:测试任意数值表达式

%如果:测试任意数值表达式

macho64:马赫64位对象文件格式

macho64:马赫64位对象文件格式

男子气概

macho32:马赫32位对象文件格式

macho64:马赫64位对象文件格式

macho32:马赫32位对象文件格式

macho64:马赫64位对象文件格式

NASM预处理器

Macro-Local标签

时报》:重复指令或数据

映射文件

有效的地址

VSYASM——Yasm微软Visual Studio 2010

*、/、/ /、%和% %:乘法和除法

VSYASM——Yasm微软Visual Studio 2010

% ifmacro:测试多行宏观的存在

多行宏

重载多行宏

*、/、/ /、%和% %:乘法和除法

%:旋转旋转宏观参数

N

NOP填充

有效的地址

DB和朋友:宣布初始化数据

数字常量

O

类型:设置符号类型

数字常量

精灵共同扩展指令

精灵扩展全球指令

默认宏参数

一元运算符:+、-、~和凹陷

NASM源代码行布局

NASM源代码行布局

表达式

ORG:二进制起源

ORG:二进制起源

NASM源代码行布局

赛格和关于

重载

重载多行宏

正常方式:%定义

NASM源代码行布局

P

NOP填充

关键表达式

关键表达式

win32:Microsoft win32对象文件

win64:PE32 +(微软win64)对象文件

当地的标签

elf64特殊符号和关于

elfx32特殊符号和关于

elfx32特殊符号和关于

elfx32特殊符号和关于

正常方式:%定义

表达式

赛格和关于

数字常量

装备:定义常量

预处理程序循环

预处理器变量:%分配

NASM汇编指令

elfx32特殊符号和关于

指定目标处理器模式

精灵扩展全球指令

伪指令

全球:导出符号

本:平面形式二进制输出

NASM源代码行布局

R

rdf:浮动动态对象文件格式

rdf:浮动动态对象文件格式

默认值:改变汇编违约

%如果:测试任意数值表达式

rdf:浮动动态对象文件格式

搬迁

elfx32特殊符号和关于

%和%推流行:创建和删除背景

% repl:重命名上下文

时报》:重复指令或数据

预处理程序循环

关键表达式

RESB和朋友:声明未初始化的数据

RESB和朋友:声明未初始化的数据

RESB和朋友:声明未初始化的数据

RESB和朋友:声明未初始化的数据

RESB和朋友:声明未初始化的数据

RESB和朋友:声明未初始化的数据

把相对寻址

%:旋转旋转宏观参数

年代

包括其他文件

win32扩展部分指令

win32扩展部分指令

部分对齐

win32扩展部分指令

本特殊符号

本特殊符号

本特殊符号

赛格和关于

赛格和关于

NASM源代码行布局

分割

分割

赛格和关于

%:旋转旋转宏观参数

*、/、/ /、%和% %:乘法和除法

*、/、/ /、%和% %:乘法和除法

% ifdef:测试单行的宏观的存在

正常方式:%定义

正常方式:%定义

大小

精灵扩展全球指令

大小:设置符号大小

elf32:可执行文件和可链接32位对象文件格式

elf64:可执行文件和可链接格式64位对象文件

INCBIN:包括外部的二进制文件

精灵扩展全球指令

有效的地址

刺穿:刺穿了调试格式

标准宏

win32扩展部分指令

标准化的部分名称

严格:抑制优化

DB和朋友:宣布初始化数据

字符串常量

字符串处理在宏

字符串长度:% strlen

绝对绝对:定义标签

win64结构化异常处理

子:%的子串

+和-:加法和减法运算符

改变和定义部分

大小:设置符号大小

标志的尺寸

精灵扩展全球指令

类型:设置符号类型

符号类型

精灵扩展全球指令

T

测试

%如果:测试任意数值表达式

% ifctx:测试上下文堆栈

% ifidn和% ifidni:测试具体文本的身份

% ifmacro:测试多行宏观的存在

% ifdef:测试单行的宏观的存在

ifid百分比、ifnum百分比,% ifstr:测试令牌类型

关键表达式

ifid百分比、ifnum百分比,% ifstr:测试令牌类型

关键表达式

NASM源代码行布局

类型

精灵扩展全球指令

类型:设置符号类型

U

一元运算符:+、-、~和凹陷

一元运算符:+、-、~和凹陷

RESB和朋友:声明未初始化的数据

elf32:可执行文件和可链接32位对象文件格式

时报》:重复指令或数据

*、/、/ /、%和% %:乘法和除法

*、/、/ /、%和% %:乘法和除法

win64结构化异常处理

USE16、USE32 USE64

USE16、USE32 USE64

USE16、USE32 USE64

%错误:用户定义的错误报告

标准宏

NASM汇编指令

V

NASM源代码行布局

本指令扩展部分

鉴别:添加文件识别

__YASM_MAJOR__等:Yasm版本

本指令扩展部分

win32:Microsoft win32对象文件

win64:PE32 +(微软win64)对象文件

win64:PE32 +(微软win64)对象文件

VC8 cv8:CodeView调试格式

VC8 cv8:CodeView调试格式

VSYASM——Yasm微软Visual Studio 2010

本指令扩展部分

VSYASM——Yasm微软Visual Studio 2010

W

弱势:创建软弱的象征

弱势:创建软弱的象征

win32:Microsoft win32对象文件

win32扩展部分指令

win32:Microsoft win32对象文件

win32扩展部分指令

win64:PE32 +(微软win64)对象文件

win64:PE32 +(微软win64)对象文件

窗户

win32:Microsoft win32对象文件

win64:PE32 +(微软win64)对象文件

win32:Microsoft win32对象文件

win64:PE32 +(微软win64)对象文件

elf64特殊符号和关于

X

elfx32:精灵32位64位处理器对象文件

elfx32特殊符号和关于

win64:PE32 +(微软win64)对象文件

win64结构化异常处理

Segmentation

xdf, xdf: Extended Dynamic Object Format

Y

Yasm Version, __YASM_MAJOR__, etc: Yasm Version

 

SRC=http://www.tortall.net/projects/yasm/manual/html/manual.html

相关文章:

  • 2021-09-01
  • 2022-12-23
  • 2021-08-28
  • 2021-12-19
猜你喜欢
  • 2022-12-23
  • 2021-12-12
  • 2021-10-06
  • 2021-11-24
  • 2022-12-23
相关资源
相似解决方案