微机原理实验报告4..

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

微机原理实验报告4..
实验报告
课程名称:《微机原理》实验第3次实验
实验名称:宏命令与⼦程序的区别
实验时间:2015年10⽉13⽇
实验地点:XXXXXX组号__________
学号:XXXX
姓名:XXX
指导⽼师:XX 评定成绩:___________
微机原理实验4
南京⼤学⼯程管理学院
⼀、实验设备:
计算机
⼆、实验⽤时:
4⼩时
三、实验内容:
1.单步运⾏实例函数NO3_Mpy_8,了解单字节⽆符号数乘法的实现⽅法。

2.编写⼦程序Mpy_16,实现双字节⽆符号数乘法。

⾃⾏定义变量,其中:
ACCALO ;存放乘数低8 位
ACCAHI ;存放乘数⾼8 位
ACCBLO ;存放被乘数低8 位和乘积第16~23 位
ACCBHI ;存放被乘数⾼8 位和乘积第24~31 位
ACCCLO ;存放乘积第0~7 位
ACCCHI ;存放乘积第8~15 位
编写Main主程序,使⽤乘数0x4015和被乘数0x3321对编写的⼦程序进⾏测试,结果应为0x0CCC71B5。

3.编写宏命令Mpy_16,实现单字节⽆符号数乘法。

编写Main 主程序调⽤宏命令并对运算结果进⾏测试。

4.使⽤反汇编⼯具Disassembly Listing单步运⾏程序,观察⼦程
序与宏命令的差异。

四、实验报告要求:
1. 程序框图和源程序清单。

2. 分析宏扩展过程,说明宏与⼦程序的差别。

五、实验结果: 1、程序框图(1)⼦程序Mpy_16


⼦程序调⽤
初始化循环计数器TEMP
将乘数ACCBHI 、ACCBLO 复制到MDHI 、MDLO

ACCAHI 、ACCBHI 、ACCALO 、ACCBLO 分别相
加,结果放⼊ACCBHI 、ACCBLO 中
ACCBHI 、ACCBLO 、ACCCHI 、ACCCLO 清零 MDHI 、MDLO 算数右移⼀位,最低位进⼊C C=1?


(2)宏命令Mpy_16
ACCBHI 、ACCBLO 带进位位右移,最低位放⼊C
中 ACCCHI 、ACCCLO 带进位位右移,最低位放⼊C 中
TEMP=TEMP-1
TEMP=0?
⼦程序返回
开始
初始化循环计数器TEMP
将乘数ACCBHI 、ACCBLO 复制到MDHI 、MDLO

ACCBHI 、ACCBLO 、ACCCHI 、ACCCLO 清零




2、源程序清单(1)⼦程序Mpy_16
list p=16f877A ; list directive to define processor
ACCBHI 、ACCBLO 带进位位右移,最低位放⼊C
中 ACCAHI 、ACCBHI 、ACCALO 、ACCBLO 分别相加,结果放⼊ACCBHI 、ACCBLO 中
ACCCHI 、ACCCLO 带进位位右移,最低位放⼊C 中 MDHI 、MDLO 算数右移⼀位,最低位进⼊C
TEMP=TEMP-1
C=1?
TEMP=0?
结束
#include ; processor specific variable definitions
__CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_OFF & _HS_OSC & _WRT_OFF & _LVP_OFF & _CPD_OFF
ACCALO EQU 0x20 ;存放加数低8位
ACCAHI EQU 0x21 ;存放加数⾼8位
ACCBLO EQU 0x22 ;存放被加数低8位
ACCBHI EQU 0x23 ;存放被加数⾼8位
ACCCLO EQU 0x24;
ACCCHI EQU 0x25;
MDLO EQU 0x26;
MDHI EQU 0x27;
TEMP EQU 0x28 ;临时寄存器
; 双字节加法⼦程序,⼊⼝地址ACCB + ACCA,出⼝地址ACC ORG 0x0000 ; 复位⼊⼝地址nop ; 兼容ICD调试⼯具,必须加nop goto Main ; 跳转⾄Main函数
Main
MOVLW 0x15;
MOVWF ACCALO;
MOVLW 0x40;
MOVWF ACCAHI;
MOVLW 0x21;
MOVWF ACCBLO;
MOVLW 0x33;
MOVWF ACCBHI;
CALL MPY_16;
NOP;
GOTO $;
ORG 0x0100
MPY_16
CALL SETUP ;
MLOOP
BCF STATUS, C ; 清进位位RRF MDHI ; MD 右移 RRF MDLO;
BTFSC STATUS, C ;判断是否需要相加
CALL Add_16 ; 加乘数⾄ MB RRF ACCBHI ; 右移部分乘积
RRF ACCBLO;
RRF ACCCHI;
RRF ACCCLO;
DECFSZ TEMP ; 乘法完成否?
GOTO MLOOP ; 否,继续求乘积
RETURN ; ⼦程序返回SETUP
MOVLW .16 ;初始化 TEMP 寄存器MOVWF TEMP
MOVF ACCBLO, W ; 乘数送MD
MOVWF MDLO;
MOVF ACCBHI,W;
MOVWF MDHI;
CLRF ACCBLO ; 清 MB
CLRF ACCBHI;
CLRF ACCCLO ;清 MC
CLRF ACCCHI;
RETURN ;⼦程序返回
Add_16
MOVF ACCALO, w ;ACCB和ACCA低半字节相加
ADDWF ACCBLO , f ;
BTFSC STATUS, C ;有进位否?
INCF ACCBHI;有,ACCB⾼字节加1,再加ACCAHI MOVF ACCAHI, w ; ACCA、ACCB⾼半字节相加
ADDWF ACCBHI, f ;
RETURN ;⼦程序返回
END;
(2)宏命令Mpy_16
list p=16f877A ; list directive to define processor #include ; processor specific variable definitions
__CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_OFF & _HS_OSC & _WRT_OFF & _LVP_OFF & _CPD_OFF
MPY_16 macro ACCALO1,ACCAHI1,ACCBLO1,ACCBHI1,ACCCLO1,ACCCHI1,MDHI1,MDLO1
,TEMP1;
SETUP
ACCALO1,ACCAHI1,ACCBLO1,ACCBHI1,ACCCLO1,ACCCHI1,MDHI1,MDLO1
,TEMP1 ;
MLOOP
BCF STATUS, C ; 清进位位
RRF MDHI1 ; MD 右移
RRF MDLO1;
BTFSS STATUS, C ;判断是否需要相加
GOTO LOOP;
Add_16
ACCALO1,ACCAHI1,ACCBLO1,ACCBHI1,ACCCLO1,ACCCHI1,MDHI1,MDLO1 ,TEMP1 ; 加乘数⾄ MB
LOOP
RRF ACCBHI1 ; 右移部分乘积
RRF ACCBLO1;
RRF ACCCHI1;
RRF ACCCLO1;
DECFSZ TEMP1 ; 乘法完成否?
GOTO MLOOP ; 否,继续求乘积
ENDM ; ⼦程序返回
SETUP macro ACCALO2,ACCAHI2,ACCBLO2,ACCBHI2,ACCCLO2,ACCCHI2,MDHI2,MDLO2 ,TEMP2; MOVLW .16 ;初始化 TEMP 寄存器
MOVWF TEMP2
MOVF ACCBLO2, W ; 乘数送MD
MOVWF MDLO2;
MOVF ACCBHI2,W;
MOVWF MDHI2;
CLRF ACCBLO2 ; 清 MB
CLRF ACCBHI2;
CLRF ACCCLO2 ;清 MC
CLRF ACCCHI2;
ENDM ;⼦程序返回
Add_16 macro ACCALO3,ACCAHI3,ACCBLO3,ACCBHI3,ACCCLO3,ACCCHI3,MDHI3,MDLO3
,TEMP3;
MOVF ACCALO3, w ;ACCB和ACCA低半字节相加
ADDWF ACCBLO3 , f ;
BTFSC STATUS, C ;有进位否?
INCF ACCBHI3;有,ACCB⾼字节加1,再加ACCAHI MOVF ACCAHI3, w ; ACCA、ACCB⾼半字节相加ADDWF ACCBHI3, f ;
ENDM ;⼦程序返回
ACCALO EQU 0x20 ;存放加数低8位
ACCAHI EQU 0x21 ;存放加数⾼8位
ACCBLO EQU 0x22 ;存放被加数低8位
ACCBHI EQU 0x23 ;存放被加数⾼8位
ACCCLO EQU 0x24;
ACCCHI EQU 0x25;
MDLO EQU 0x26;
MDHI EQU 0x27;
TEMP EQU 0x28 ;临时寄存器
; 双字节加法⼦程序,⼊⼝地址ACCB + ACCA,出⼝地址ACC ORG 0x0000 ; 复位⼊⼝地址nop ; 兼容ICD调试⼯具,必须加nop goto Main ; 跳转⾄Main函数
Main
MOVLW 0x15;
MOVWF ACCALO;
MOVLW 0x40;
MOVWF ACCAHI;
MOVLW 0x21;
MOVWF ACCBLO;
MOVLW 0x33;
MOVWF ACCBHI;
MPY_16
ACCALO,ACCAHI,ACCBLO,ACCBHI,ACCCLO,ACCCHI,MDHI,MDLO,TEMP; NOP; GOTO $;
END;
3、程序运⾏结果截图
(1)⼦程序Mpy_16
⼦程序运⾏结果
(2)宏命令Mpy_16
宏指令运⾏结果4、分析宏扩展过程,说明宏与⼦程序的差别(1)⼦程序Mpy_16的反汇编结果
⼦程序的反汇编代码1
⼦程序的反汇编代码2(2)宏命令Mpy_16的反汇编结果
0000 0000 NOP
0001 2802 GOTO 0x2
0002 3015 MOVLW 0x15
0003 00A0 MOVWF 0x20
0004 3040 MOVLW 0x40
0005 00A1 MOVWF 0x21
0006 3021 MOVLW 0x21
0007 00A2 MOVWF 0x22
0008 3033 MOVLW 0x33
0009 00A3 MOVWF 0x23
000A 3010 MOVLW 0x10
000B 00A8 MOVWF 0x28
000C 0822 MOVF 0x22, W
000D 00A6 MOVWF 0x26
000E 0823 MOVF 0x23, W
000F 00A7 MOVWF 0x27
0010 01A2 CLRF 0x22
0011 01A3 CLRF 0x23
0012 01A4 CLRF 0x24
0013 01A5 CLRF 0x25
0014 1003 BCF 0x3, 0
0015 0CA7 RRF 0x27, F
0016 0CA6 RRF 0x26, F
0017 1C03 BTFSS 0x3, 0
0018 281F GOTO 0x1f
0019 0820 MOVF 0x20, W
001A 07A2 ADDWF 0x22, F
001B 1803 BTFSC 0x3, 0
001C 0AA3 INCF 0x23, F
001D 0821 MOVF 0x21, W
001E 07A3 ADDWF 0x23, F
001F 0CA3 RRF 0x23, F
0020 0CA2 RRF 0x22, F
0021 0CA5 RRF 0x25, F
0022 0CA4 RRF 0x24, F
0023 0BA8 DECFSZ 0x28, F
0024 2814 GOTO 0x14
0025 0000 NOP
0026 2826 GOTO 0x26
2007 2394 CALL 0x394
(3)宏扩展过程
宏扩展只是⽤原来宏定义中的若⼲条汇编指令代替程序中的“⼀条”宏指令插⼊到此宏指令位置处,进⾏直接替换功能。

(4)宏与⼦程序的差别
宏指令(宏扩展)只是⽤原来宏定义中的若⼲条汇编指令代替程序中的“⼀条”宏指令插⼊到此宏指令位置处,进⾏直接替换功能,⽽⼦程序是调⽤⼀个程序块;宏指令通过花费空间来节省时间,⼦程序通过花费时间来节省空间。

5、两个⽆符号数相乘的本质
两个⽆符号数相乘,其本质就是根据被乘数的位上是否为1,为1则临时寄存器结果加上乘数再右移⼀位,为0则临时寄存器结果直
接右移⼀位,当乘数所有位数判断结束则临时寄存器⾥存放的结果即为所求结果,不过要注意单字节数相乘右移⼀位和双字节数相乘右移⼀位的区别,单字节右移⼀位只需⼀次RRF指令,双字节则需要先对⾼位使⽤RRF指令,再对低位使⽤RRF指令。

六、实验数据误差分析及反思:
1、在编译汇编程序时,由于END指令放错位置,导致程序编译失败,后来发现END指令应该放在整个汇编程序的最后,⽽不是主程序的最后;
2、两个⽆符号数相乘,其本质就是根据被乘数的位上是否为1,为1则临时寄存器结果加上乘数再右移⼀位,为0则临时寄存器结果直接右移⼀位,当乘数所有位数判断结束则临时寄存器⾥存放的结果即为所求结果,不过要注意单字节数相乘右移⼀位和双字节数相乘右移⼀位的区别,单字节右移⼀位只需⼀次RRF指令,双字节则需要先对⾼位使⽤RRF指令,再对低位使⽤RRF指令;
3、使⽤反汇编⼯具可以很好地发现⼦程序和宏指令之间的区别,宏指令(宏扩展)只是⽤原来宏定义中的若⼲条汇编指令代替程序中的“⼀条”宏指令插⼊到此宏指令位置处,进⾏直接替换功能,⽽⼦程
序是调⽤⼀个程序块;
4、当编译系统报错时,应该先检查⼀下程序语法是否存在错误,如果有则优先改正,然后再解决程序中出现的逻辑错误,这样做会使得程序完成⼯作快速⽽有效;
七、实验总结:
1、宏指令只是程序的直接替换,通过花费空间来节省时间,⽽⼦程序是调⽤⼀个程序块,通过花费时间来节省空间;
2、宏指令应该放在整个汇编程序主程序的前⾯,不然在程序编译时会报错;
3、在将⼦程序的代码改写成宏指令的代码时,不仅要加⼊宏指令的代码,还要注意BTFSC、BTFSS等指令是否需要调整逻辑结构,否则程序改写后可能会产⽣错误的结果;
4、在进⾏双字节⽆符号数的乘法时,在移位过程中应该注意,先将⾼位右移,再将低位右移,这样最终结果才正确;
5、END指令应该放在整个汇编程序的最后,⽽不是主程序的最后,。

相关文档
最新文档