1、S12X汇编程序设计与实例,3.4.0 汇编语言程序基础特点:与硬件相关不易移植,高效、直接面对硬件、代码量小;程序:完成特定任务的指令的集合,程序设计语言:机器语言(二进制指令代码,可直接执行) 汇编语言(特定助记符指令语句,须汇编) 高级语言(通用高级语句,须编译)单片机应用系统的程序,多用汇编语言编制(*.asm文件)或C 一个汇编程序语句一条单片机指令 多个汇编语言语句汇编语言程序(源代码)注:程序需要特定的编译程序进行编译,生成二进制机器码,3.4.1汇编语言指令格式与伪指令1.汇编指令格式 标号: 操作码 操作数1 ,操作数2 ;注释标号-该指令的符号地址,标定程序入口或转移位置
2、注:标号必须以字母开始,分大小写。 用途:数据定义、子程序、中断、循环、跳转。操作码-助记符,指令所实现的操作功能 注:不分大小写;前面无标号时,至少应保留一个空格操作数-参加操作的数据对象,常数、符号或表达式 注:寄存器寻址已归纳到隐含寻址中,当操作数部分出现寄存器时,一定是寄存器间址;分大小写;注释-为方便阅读、修改而加的注释,可有可无 注:以“;”开始,本行之后的内容不再编译,2.数据的表示方法 Freescale规定,加前缀$ 十六进制% 二进制 八进制 ASCII无 十进制,# 立即数的标记如:LDAA #$32 ;立即数 LDAA $32 ;地址,3. 汇编程序伪指令 汇编程序使用
3、的辅助性语句,不生成机器码.1、起始地址伪指令 ORG ORG $2000H START: LDAA #$FF2、赋值伪指令 EQU PORTB EQU $0001 BIT0 EQU %00000001 BSET PORTB, BIT0 ;等价于 BSET $0001, %00000001,Vtimovf: equ $0000FFDEVtimch7: equ $0000FFE0Vtimch6: equ $0000FFE2Vtimch5: equ $0000FFE4Vtimch4: equ $0000FFE6Vtimch3: equ $0000FFE8Vtimch2: equ $0000FFEA
4、Vtimch1: equ $0000FFECVtimch0: equ $0000FFEEVrti: equ $0000FFF0Virq: equ $0000FFF2Vxirq: equ $0000FFF4Vswi: equ $0000FFF6Vtrap: equ $0000FFF8Vcop: equ $0000FFFAVclkmon: equ $0000FFFCVreset: equ $0000FFFE;,;* PORTB - Port B Register; 0x00000001 *PORTB: equ $00000001 ;* PORTB - Port B Register; 0x0000
5、0001 *; bit numbers for usage in BCLR, BSET, BRCLR and BRSETPORTB_PB0: equ 0 ; Port B Bit 0PORTB_PB1: equ 1 ; Port B Bit 1PORTB_PB2: equ 2 ; Port B Bit 2PORTB_PB3: equ 3 ; Port B Bit 3PORTB_PB4: equ 4 ; Port B Bit 4PORTB_PB5: equ 5 ; Port B Bit 5PORTB_PB6: equ 6 ; Port B Bit 6PORTB_PB7: equ 7 ; Port
6、 B Bit 7; bit position masksmPORTB_PB0: equ %00000001mPORTB_PB1: equ %00000010mPORTB_PB2: equ %00000100mPORTB_PB3: equ %00001000mPORTB_PB4: equ %00010000mPORTB_PB5: equ %00100000mPORTB_PB6: equ %01000000mPORTB_PB7: equ %10000000,4.常量存储 (1)字节常量伪指令 FCB ( DC.B ) ORG $0200 TABLE: FCB $13,18,N1+6,21 (2)双
7、字节常量伪指令 FDB ( DC.W ) ORG $1000 LIST: FDB $0519, $2000 (3)字符量伪指令 FCC ORG $2000 STAR: FCC ABCD注:定界符可以是()、(/)、(”),建议使用(),5.关于数据变量伪指令使用需要注意的问题 FLASH 常数可以读,不能修改; RAM 常数可以读写;绝对地址方式编译的程序, 可以将数据定义在RAM区域, 即$0000-$4000;以可以重定位的方式编译,需要建立不同的数据段。 常量段定义在FLASH中; 数据段定义在RAM 中 ; 不能用ORG伪指令将FLASH中的变量强制定义到RAM;数据段 仅使用DS伪指
8、令的数据段;,可重定位方式的实例-,C1内容方式变化FG 内容没有变化不是18仍然是初始的1,伪指令ORG不能将FLASH段数据定位到RAM,绝对地址方式实例,Freescale MCU编程几个提示-1、程序是被编译成二进制码放在程序存储器(FLASH)的,通过PC递加,自动逐条执行;PC值指向的下一条将要执行的指令。2、程序处理主要是通过访问寄存器、数据存储器(RAM)的各单元实现所需功能要求的,而CPU寄存器(A,B,X,Y,CCR)是经常要用到的工作寄存器。3、理解MCU的存储器空间分配图,寄存器、RAM、FLASH是统一编址在64K地址空间的,每单元8位;访问寄存器使用其功能符号形式,
9、访问RAM区可用16位地址形式($xxxx)。,5、适当伪指令:辅助编程,便于修改、理解等。6、注意格式:大写、缩进、对齐、注释。7、编程方法: 熟悉指令,理解范例,套用实践,举一反三 由小到大,优化整理,结合硬件,完备应用,4、主程序通常是:初始化以后,循环等待或原地等待。 子程序用标号定义开始,用RTS结束; 主程序用BSR或JSR调用之; 中断服务子程序也用标号定义开始,结束则用RTI;需要声明中断向量对应的程序入口,其执行是当中断发生时自动被执行的。,3.4.2 汇编语言程序设计实例【例】2个8字节数求和,结果保存在被加数所在地址中。,;*ADD8: LDX #$0B01 LEAY 8
10、,X LDAB #8 CLC LOOP: LDAA X ADCA 1,Y+ STAA 1,X+ DBNE B,LOOP,RAM区,计数器控制次数16位加法指令没有带C加法指令没有M+MLDAA 不影响C位自动加减寻址方便X,Y作为指针使用,【例】将A中的两个4位十六进制数转换为ASCII码,分别存入$1080、$1081中。(09的ASCII码:$30$39,AF:$41$46),;*;子程序TRANS:十六进制数转换为ASCII码;入口参数:(A)=十六进制数,高4位为0;出口参数:(B)=ASCII码;*TRANS: PSHX ;压栈 LDX #TABLE ;置表地址 LDAB A,X ;
11、查表,(X+A)B PULX ; 出栈 RTS ; 返回TABLE: FCC 0123456789ABCDEF,;主程序段* ORG $8000HEXA: TFR A,X ANDA #$0F JSR TRANS STAB $1080 TFR X,A LSRA LSRA LSRA LSRA JSR TRANS STAB $1081 ,讨论:1.子程序压栈,保存数据 2.子程序定义入口出口参数 3.TABLE 是ASCII码,【例】比较RAM区内两相邻单元中无符号数的大小,按小数在前、大数在后重新存放(首址在$2000)。若等则Y寄存器加1。,LDX #$2000 ;首地址 CLC ;C清零 LD
12、Y #0 ;Y清零BEGIN: LDAA 0,X ;(0+X)A LDAB 1,X ;(1+X)B CBA ;(A)-(B) BCS DONE ;减有借位(前小后大),无需调整,跳转 BEQ FLAG ;相等,跳转 STAA 1,X ;A(1+X) STAB 0,X ;B(0+X) BRA DONE ;调整完毕,跳转FLAG: INY ;Y+1Y DONE: BRA * ;结束,EXTERN CHAR YEAR , MONTHCHAR M-LENGTH() IF (MONTH = 2 ) IF ( YEAR%4) RETURN (28); ELSE RETURN (29) ELSE IF( M
13、ONTH=4| MONTH=6|MONTH=9|MONTH=11) RETURN(30); ELSE (RETURN (31); ,汇编语言编程技巧- 计算年月对应的天数,变换后: 大月是奇数, 小月是偶数;方法: 大于等于8月加1;算法:30+bit0;特殊: 2月是奇点, 需要特殊处理;,算法分析,入口: MONTH , YEAR ;出口:A寄存器返回天数。M_LENGTH: LDAA #30 ; A寄存器存放天数,初始30天 LDAB #2 CMPB MONTH ;是二月特殊月份? BEQ FEBRARY ;是, 转到二月处理 LDAB MONTH ;进入非二月份 CMPB #8 ;变换
14、,使得大月始终为奇数 BLT ODDBIG INCBODDBIG: ANDB #1 ;寄存器B 大月为1, 小月为0 ABA ; A寄存器为返回的天数30 或31天 RTSFEBRARY: DECA ;二月最大29天 LDAB YEAR ;取年 ANDB %00000011 ;被4整除后的余数 BEQ FINI ;闰年? 是返回29天 DECA ;否 返回28天FINI: RTS END,汇编特点:AND 实现取余数效率高;变换用INC指令快、短操作在寄存器进行,3. 数据查表程序【例】数码管显示按键数值。,;*COUNT1 EQU $2000 DELAY: CLC LDAA #$00 STA
15、A COUNTER1 LDY #TABLE2LP3: LDAB Y INY LDAA PORTA SBA BEQ DISPLAY1 INC COUNTER1 BRA LP3,DISPLAY1: LDAA #$00 STAA PTT LDAB COUNTER1;相对量COUNTER1: LDY #TABLE3 LDAA B,Y STAA PTP RTS,TABLE2: FCB $ee,$de,$be,$7e,$ed,$dd,$bd,$7d,$eb,$db,$bb,$7b,$e7,$d7,$b7,$77 ;4x4行列键值,预定义的,16个可能的读回值TABLE3: FCB $f9,$a4,$b0,
16、$99,$92,$82,$f8,$80,$90,$c0,$88,$83,$c6,$a1,$86,$8e;共阳字符编码: 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, A, B, C, D, E, F,讨论:1.假设A口输入一定是规定范围 2.变量COUNTER1可以不用; 3. #TABLE2 4.BEQ DISPLAY1?,CPU执行时间: T = N x TB T-总执行时间 , N-总时钟周期数, TB-总线时钟周期(例如:晶振频率为16MHz,则总线时钟频率为8MHz,TB = 1/8M=125ns )【例】2ms延时。(晶振频率为16MHz) 则需N=T / TB =
17、2ms / 125ns = 16000程序运行:N=4+2+3+(1+3)(TCOUNT-1)+(1)+3+5 故:TCOUNT=3996.253996,2. 延时子程序硬件延时-内部定时器实现,精确,不占CPU软件延时-循环执行指令,简单方便,定时精度低,占用CPU,;* JSR DELAY1 ;4;* TCOUNT EQU 3996 ;无 DELAY1: PSHX ;2 LDX #TCOUNT;3DLOOP: DEX ;1 BNE DLOOP ;3/1 PULX ;3 rts ;5,【又例】双重循环的100ms延时。忽略配合指令的执行间,粗略估算:内循环=200 x (1+1+3)T =1
18、000T总时间=100x1000T =100000T2MHz晶振时,总线频率=1MHz T=1us 子程序延时时间即100ms,;/;子程序DELAY:利用寄存器X、Y,; 执行两重循环实现延时。;/DELAY: PSHX PSHY LDX #100DELAY1: LDY #200DELAY2: NOP ;1T NOP ;1T DBNE Y,DELAY2 ;3T DBNE X,DELAY1 PULY PULX RTS,本章习题:列出S12汇编程序设计中的数据表示方法?什么是伪指令?常用伪指令的功能有哪些?读懂各个程序实例。编写汇编程序:延时100ms的子程序。(用X、Y,实现两重循环)编写汇编程序:10个整数的冒泡法排序程序。,