复位后,8051微处理器开始从CODE地址0执行程序。Intel/Atmel WM 25的起始执行地址为FF0000。有些类型的程序代码必须被置于该地址。我们可以使用绝对段强制程序代码进入该地址。下面的例子被用在Cx51启动程序中,从复位地址转移到初始化代码的开始。
AX51和A251支持绝对段控制,以与A51兼容。AX51和A251把伪指令CSEG,DSEG,XSEG,ISEG和BSEG翻译为一个普通段伪指令。我们用CSEG AT 0伪指令放置在地址0000h的程序代码,实现一个到STARTUP标号的跳转。
/
默认段(Default Segment):
默认情况下,当Ax51开始处理一个汇编源文件模块时,它认为CODE段已被选择,并把位置计数器初始化到0000h(FF0000h)。这使得我们可以在不指明任何可重定位或绝对段的情况下来创建程序。
堆栈段(Stack Segment)
x51架构使用一个硬件堆栈为CALL指令存储返回地址,也用于PUSH和POP指令的临时存储。使用这些指令的8051应用程序必须把堆栈指针设置到一个不允许其它变量使用的存储区域。
对于传统的8051,必须定义一个堆栈段,堆栈空间必须按下面的方法保留。这种定义也适用于扩展的8051和251,而一般情况下,这些控制指令也可以在其它区域设置堆栈。
STACK | SEGMENT | IDATA | |
RSEG | STACK | ; 选择堆栈段 | |
DS | 10h | ; 保留16个字节的空间 |
然后,你必须在程序的开始初始化堆栈指针。
CSEG | AT | 0 | ; 复位向量 |
JMP | STARTUP | ; 跳转到启动代码 | |
STARTUP: | ; 在复位时执行的代码 | ||
MOV | SP, #STACK - 1 | ; 装入堆栈指针 |
对于Philips 80C51MX或者Intel/Atmel WM 251,可以定义一个堆栈段,而且必须按下面的方法保留堆栈空间。
STACK | SEGMENT | EDATA | |
RSEG | STACK | ; 选择堆栈段 | |
DS | 100h | ; 保留256个字节的空间 |
然后,你必须在程序的开始初始化堆栈指针。
CSEG | AT | 0 | ; 复位向量 |
JMP | STARTUP | ; 跳转到启动代码 | |
STARTUP: | ; 在复位时执行的代码 | ||
;为Philips 80C51MX设置堆栈 | |||
ORL | MXCON, #0x02 | ; 使能扩展的堆栈 | |
MOV | SPE, #HIGH (STACK - 1) | ; 装入堆栈高字节 | |
MOV | SP, #LOW (STACK - 1) | ; 装入堆栈低字节 | |
为Intel/Atmel WM 251设置堆栈 | |||
MOV | DR60, #STACK - 1 | ; 装入堆栈指针 |
如果你要使汇编接口到C,你可能不需要设置堆栈。这在C启动代码中已经为你做好了。
//
普通段(Generic Segment)
普通段具有一个名称和一个存储空间类型,以及其它一些属性。在不同目标模块中的同名普通段被认为是同一个段的组成部分,叫做部分段(Partial Segment)。这些段在连接时由连接/定位器组合起来。
普通段是用SEGMENT伪指令创建的。我们必须指定段的名称、段的存储空间类型,当我们创建一个可重定位的段时还要指定一个可选的重定位类型和定位类型(alignment type) 。
例子
MYPROG SEGMENT CODE |
上面的代码定义一个名为MYPROG的段,存储空间类型为CODE。意思是说MYPROG段中数据将被定位在x51的代码或程序区域中。
一旦你定义了一个可重定位段的名称,我们就必须用RSEG伪指令选择那个段。当使用RSEG选择一个段时,那个段就成为Ax51用于后续代码和数据的活动段,直到有RSEG或绝对段伪指令改变当前活动段为止。
例子
RSEG MYPROG |
将选择上面定义的MYPROG段。
典型的,汇编程序被放在普通段中。如果我们要使汇编程序与C接口,那么所有的汇编程序必须被放置在单独的普通段中,而且段名必须遵守Cx51的标准。参见编译器用户向导获取有关汇编程序与C接口的更多信息。