一、 金水明32051基本指令集
A351是基于金水明32051指令集的汇编语言,A51是Keil编译器基于8051指令集的汇编语言。除了 IDATA 段和少量的宏语言规范外, A351 汇编语言支持 A51 汇编语言的绝大部分语法规范,绝大部分的用A51汇编语言编写的程序金水32051编译器都能直接编译通过,生成正确的机器码。
金水明32051指令集是专门为满足8位单片机C语言要求而设计的抽象指令集,8051指令集是金水明32051指令集的完全子集,金水明32051指令集由8051指令集+扩展指令集组成。
(1)金水明32051-L0寄存器和存储空间。
寄存器是指令集的操作对象,8051寄存器是金水明32051寄存器的完全子集,称为"金水明32051-L0寄存器"。
8051单片机的全部存储空间是金水明32051指令集存储空间的完全子集,称为"金水明32051-L0存储空间"。L0空间包括64KB的CODE程序空间,64KB的XRAM扩展RAM空间,256字节的直接寻址DATA内部RAM空间,256字节的间接寻址IDATA内部RAM空间和256位的位寻址BIT空间。
(2)金水明32051-L1寄存器。
金水明32051的寄存器由全部的8051寄存器、扩展的两个16位指针寄存器和组合的两个32位通用寄存器组成。后面两者称为"金水明32051-L1寄存器"
1)两个16位指针寄存器为BP和VP,主要用于函数的参数和局部变量的存取,它们只支持XRAM空间的间接寻址和间接偏移寻址。
由于8位8051单片机没有可以直接对应的16位寄存器可用,故采用了在DATA空间分配固定的地址来实现。对于8051内核单片机16位的操作只能有8位CPU的指令来完成,所以每个扩展寄存器用高低两个8位寄存器组成,在金水32051编译器中它们的地址分配如下(大端模式):
2)两个32位的通用寄存器为EAX和EBX,主要用与各种数值运算和少量的C语言数组和指针变量的存取。作为寻址寄存器时它们只支持XRAM空间的变量存取。
8位的8051单片机有8个通用寄存器可用,金水明32051将它们组合起来作为16位和32位通用寄存器,组合方式参考80x86指令集,其组合方式如下:
其中为了与8051的汇编语言A51有区别,在金水明32051扩展指令集中,8位寄存器的取了不同的名称BR0~BR7,但它和单片机的R0~R7是同一组寄存器,使用时请注意。
32位的操作用EAX和EBX来完成,16位的操作主要用AX和BX来完成,8位的操作主要用BR7和BR3来完成。
在金水明32051指令集中,用户使用8051指令时,8051寄存器和状态的变化与8051指令集相同,而使用扩展指令时,所有的8051寄存器和状态都可能改变了。最典型的例子是进行两32位浮点数的四则运算和关系运算。
由于 16 位和 32 位的操作只能有 8 位 CPU 的指令和对应的来完成,原则上每条 16 位和 32 位的金水明 32051 扩展指令操作完成后, CPU 的全部寄存器 R0~R7 、 DPL 、 DPH 、 ACC 、 B 、 PSW 都改变了。
二、 金水明32051扩展指令格式
金水明32051扩展指令集主要是针对CODE、XRAM和DATA空间的存取指令和16位、32位的运算指令。
金水明32051扩展指令绝大多数是"非对称指令":每条指令不是对所有的寄存器都适用,源寄存器和目标寄存器是固定的,不一定能对调位置。比如16位和32位的乘除法指令。以下将金水明32051扩展指令简称为"351指令",8051指令简称为"51指令"。
(1)操作数
金水明32051指令的操作数有三种寄存器、变量和立即数。寄存器的数据长度可以从它们唯一的名称来区分,但是变量和立即数就需要额外的修饰符来确定。
寄存器操作数由寄存器名称确定,不再附加其他修饰成分。
(2)操作符
为了明确区分351指令采用与51指令完全不同的操作符,包括8位操作的指令。尤其是对于不同的存储空间,351指令使用操作符,不像51指令一路MOV到底。
(3)立即数表达式与变量表达式
用符号"#"开头的操作数称为立即数表达式,否则称为变量表达式。立即数表达式的值是操作数本身,变量表达式的值是一个地址,指令的操作数是存放在该地址中的数。
比如指令:"MVR AX, # 0x200"是将一个数值512放入R6R7寄存器对中。
比如指令:"LDX AX, 0x200"是将XRAM空间中存放在地址512中的字节数据寄存器R6中,将地址513中的字节数据寄存器R7中。金水明32051指令集采取"大端地址模式"。
假设有数组int Z[10],则
指令:"LDX BX, Z+8"是将数组元素Z[4]中存放的值放入R6R7寄存器对中。
指令:"MVR BX, # Z+8"是将数组元素Z[4]的地址放入R6R7寄存器对中,这对应C语言的取地址操作"&Z[4]"。
由于C351程序中的变量都是要进行重定位的 ,所以编写程序时并不能知道数组Z具体的存放地址,上面的语句在经过金水32051编译器的模块连接和重定位后,在二进制机器码中能给出正确的绝对地址。
(4)A351汇编语言长度定位修饰符
在汇编语言中,没有像C语言的整数、长整数这样的数据类型定义,汇编语言中的地址标识符只表明变量的地址位置,没有在其中存放的数据的长度信息,因此在汇编语言中需要关于变量的长度定位修饰符。
A351保持A51的长度定位修饰符:
字节长度定位修饰符: BCYE、BCYE0、BCYE1、BCYE2、BCYE3
16位数据长度定位修饰符: WORD、WORD2
32位数据长度定位修饰符: DWORD
三、 金水明32051扩展指令集
金水明32051扩展指令集分为7个部分:
(1)MVR 寄存器传送指令。比如
MVR BR1, BR0 ;
MVR VP, AX ;
MVR EAX, EBX;
MVR BR7, # 0x1234 ;
MVR AX, # 1234 ;
MVR EBX, # 0x1234567890 ;
// ---- 浮点数 -------------------------
MVR EAX, # 1.2345 ; // 1.2345 = 0x3F9E0419
MVR EAX, # 1.0 ; // 1.0 = 0x3F800000
(2)变量堆栈操作指令。
使用VP寄存器的堆栈称为"变量堆栈"。变量堆栈只在XRAM空间放数据,并不包括函数调用的返回地址,而且8051也不可能执行XRAM的指令,可以提高程序运行的安全性。
比如:
PUSHV EAX ; 4字节
PUSHV BX ; 2字节
PUSHV BR5 ; 1字节
POPV EAX ; 4字节
POPV BP ; 2字节
POPV BR0 ; 1字节
// ---- 数值0 进栈 ---------------------------
PUSHZ 12 ;
// ---- 分配变量空间 ---------------------------
VP_ADD -4 ; 分配内存
VP_ADD 4 ; 释放内存
(3)DATA空间操作指令。比如
LDD BX, 0x34 ;
LDD EAX, X1+2 ;
STD P2M1 , # 0x00 ;
STD P2 , # 0xFF ;
(4)CODE空间操作指令。比如:
LDC BR7, 0x12 ;
LDC BX, Z ;
(5) XDATA空间操作指令。比如:
STX CNT, EAX ;
STX main?Loop_Counter, EAX ;
LDX EAX, main?Loop_Counter ;
(6)变量空间操作指令。比如:
LDV EAX, @BP +i ;
STV @BP +i, EAX ;
(7)算术运算指令。比如32位除法:
DIVS EAX, EBX ; --> EAX/EBX
DIVU EAX, EBX ; --> EAX/EBX
DIVF EAX, EBX ; --> EAX/EBX
(8)二进制运算指令。比如AND运算:
BINAND EAX, EBX ; --> EAX
BINAND AX, BX ; --> AX
BINAND BR7, BR3 ; --> BR7
(9)关系运算指令。比如大于运算:
GTF EAX, EBX ; --> EAX
GTS EAX, EBX ; --> EAX
GTS AX, BX ; --> AX
(10)逻辑运算指令。比如"或者"运算:
LORF EAX, EBX ; --> EAX
LORX EAX, EBX ; --> EAX
LORX AX, BX ; --> AX
LORX BR7, BR3 ; --> BR7