|
一、金水明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
|