plan9汇编⼿册(重要!!持续更新,维护!!)
我进⼊华为公司后,做开源⽣态的⼯作。在⼯作时需要⽤到plan9汇编指令,现在我把⼀些plan9的⼀些东西放在这⾥,希望对⼤家有所帮助。
寄存器:
1)汇编程序中所有预定义好的符号都是⼤写的。数据寄存器从R0到R7;地址寄存器从A0到A7;浮点寄存器从F0到F7。
2)其中,A6中的⼀个指针被C编译器⽤来指向数据,这样可以更加频繁的使⽤短地址;A6的值是常量,必须在C程序初始化外部定义的符号a6base的地址时设置。
3)在汇编器中定义了以下硬件寄存器:CAAR, CACR, CCR, DFC, ISP, MSP, SFC, SR, USP, VBR;
4)汇编器还定义了⼀些操纵堆栈的伪寄存器: FP, SP和 TOS。
FP 是栈帧指针,因此 0(FP) 是第⼀个参数, 4(FP) 是第⼆个参数,依此类推。
SP 是本地堆栈指针,其中保存了⾃动变量; 0(SP) 是第⼀个⾃动的,依此类推。
TOS 是堆栈顶部的寄存器,⽤于将参数推送到过程,保存临时值等。
5)汇编器和加载器跟踪这些伪寄存器。名称 A7 指的是硬件堆栈指针,但要⼩⼼混合使⽤ A7 和上述与堆栈相关的伪寄存器,这会造成⿇烦。还要注意, 加载程序会观察PEA指令来更改SP,因此会在所有返回之前插⼊相应的弹出窗⼝。汇编器接受要附加到FP 和 SP ⽤途的类似标签的名称 ,例如 p + 0(FP),以帮助记录 p 是例程的第⼀个参数。该名称位于符号表中,但对程序结果没有任何意义。
指向数据
1)所有外部引⽤必须相对于某些伪寄存器( PC (虚拟程序计数器)或 SB (“静态基数”寄存器))进⾏。 PC 计算指令,⽽不是数据字节。例如,要跳转到第⼆条指令,即跳过⼀条指令,可以写⼀条
BRA 2(PC)
标签允许,如
BRA return
NOP
return:
RTS
2)使⽤标签时,没有 (PC) 注释。伪寄存器 SB 是指程序的地址空间的开头。因此,对全局数据和过程的引⽤被写为SB的偏移量 ,如MOVL    $array(SB), TOS
将全局数组的地址压⼊堆栈,推送数组的第⼆个(4字节)元素。注意偏移量的使⽤;
MOVL    array+4(SB), TOS
寻址模式的完整列表如下。同样,⼦例程调⽤必须使⽤ SB:
BSR exit(SB)
静态变量具有语法
local<>+4(SB)
在<> 将在加载时由⼀个唯⼀的整数填充。
3)程序启动时必须执⾏
MOVL    $a6base(SB), A6
寻址模式
所有汇编程序都共享简单的寻址模式。出于完整性考虑,此处列出所有68020寻址模式的表格,因为该机器设置最丰富。在该表中, 如果可以忽略零,o 是⼀个偏移量; d 是位移,它是介于-128和127之间的常数。列出的许多模式具有相同的名称。仔细检查格式将显⽰正在应⽤的默认值。
定义数据
1)将数据放⼊指令流中很容易:伪指令 LONG 和 WORD (但不是 BYTE)放置适当⼤⼩的单个参数的值,例如:
LONG    $12345  //  将12345(10进制)放置在指令流中
在数据部分中放置信息会更加痛苦。伪指令 DATA 提供了两个参数来完成这项⼯作:放置项⽬的地址(包括其⼤⼩)和放置在那⾥的值。例如,要定义⼀个 包含字符 abc 和终⽌null 的字符数组 数组:
DATA    array+0(SB)/1, $’a’
DATA    array+1(SB)/1, $’b’
DATA    array+2(SB)/1, $’c’
GLOBL  array(SB), $4
或者:
汇编指令有多少个
DATA    array+0(SB)/4, $"abc\z"
GLOBL  array(SB), $4
注意:
1)“/1”  表⽰字节数, GLOBL 表⽰全球标志和 $ 4 表⽰符号多少字节占据。未初始化的数据将⾃动归零。
2)字符 “\z”等效于C中的 \ 0。DATA 语句中 的字符串 最多可包含⼋个字节。分段构建更⼤的字符串。DYNT 和 INIT这两个伪指令允许(已经过时的)Alef编译器在加载阶段构建动态类型信息。该 DYNT 伪指令有两种形式:
DYNT    , ALEF_SI_5+0(SB)
DYNT    ALEF_AS+0(SB), ALEF_SI_5+0(SB)
在第⼀种形式中, DYNT 将符号定义为⼀个⼩的唯⼀整数常量,由加载程序选择,该常量是字长的倍数。在第⼆种形式中, DYNT 以相同的⽅式定义第⼆个符号,将第⼀个符号指定的数组中最近定义的⽂本符号的地址放置在第⼆个符号的值定义的索引处,然后调整⼤⼩相应的数组。
该 INIT 伪指令采⽤相同的参数作为 数据 的语句。它的符号⽤作数组的基础,数据项以最新DYNT 伪指令指定的偏移量安装在数组中 。数组的⼤⼩会相应调整。
定义程序
1)⼊⼝点由伪操作TEXT定义,伪操作TEXT以函数的名称(包括普遍存在的(SB))和要在堆栈上预分配的⾃动存储的字节数作为参数。当操作时 ,该字节数通常为零,编写汇编语⾔程序。这是⼀个返回其两个参数之和的完整过程:
TEXT    sum(SB), $0
MOVL    arg1+0(FP), R0
ADDL    arg2+4(FP), R0
RTS
2)TEXT 伪操作的可选操作是中间参数, 是加载程序选项的位字段。当为程序的其余部分启⽤了性能分析时,将1位置1会暂停性能分析。例如,
TEXT    sum(SB), 1, $0
MOVL    arg1+0(FP), R0
ADDL    arg2+4(FP), R0
RTS
arm
1)汇编程序可通过 R14 和 PC来访问 R0。堆栈指针为 R13,链接寄存器为 R14,静态基址寄存器为 R12。 R0 是返回寄存器,也是保存⼦例程第⼀个参数的寄存器。plan9的C中的外部寄存器从R10 向下分配 。 加载程序将R11⽤作临时寄存器。汇编器⽀
持 CPSR 和 SPSR 寄存器。它还知道协处理器寄存器 C0 ⾄ C15。浮动寄存器为 F0 通过 F7, FPSR 和 FPCR。
2)与其他架构⼀样,加载和存储称为 MOV,例如 MOVW ⽤于加载字或存储字,⽽ MOVM ⽤于加载或存储多个字,具体取决于操作数。
3)指令的后缀⽀持寻址模式: .IA (之后递增) 、. IB (之前递增) 、. DA (之后递减)和 .DB (之前递减)。这些只能与MOV 指令⼀起使⽤ 。多重移动指令 MOVM使⽤括号定义寄存器范围,例如 [R0-R12]。特殊 MOVM 寻址模式位 W,U,和 P 以相同的⽅式写⼊,例如,  MOVM.DB.W. A .S 。suffix后缀允许 MOVM 指令到访问⽤户在另⼀个处理器模式下,R13 和 R14。⼆进制运算符<< (逻
辑左移), >> (逻辑右移), -> (算术右移)和@> (右旋转)⽀持寻址模式下的 移位和 旋转。例如 R7 >> R2或 R2 @> 2。汇编器不⽀持通过移位表达式进⾏索引;只有名称可以被双重索引。
4)任何指令之后可以是⼀个后缀,使指令有条件的: .EQ, .NE,等等,如在ARM⼿册,利⽤同义词 杂项⽂件 (对于 .CS)和 .LO (对于 .CC),例如 添加。 在ARM允许下,算术和逻辑指令可以带有 .S后缀来设置条件代码。
5)MCR 和 MRC 协处理器指令的语法在 很⼤程度上与⼿册中的内容相同,并进⾏了常规调整。汇编程序仅直接⽀持编译器使⽤的ARM浮点协处理器操作: CMP, ADD, SUB, MUL和 DIV,所有 后缀均带有 F 或 D后缀,⽤于选择单精度或双精度。浮点加载或存储成
为 MOVF 和 MOVD。转换指令还通过移动指定: MOVWD, MOVWF, MOVDW, MOVWD, MOVFD和 MOVDF。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。