微机原理实验3汇编语言程序设计.docx

上传人:b****4 文档编号:3657028 上传时间:2022-11-24 格式:DOCX 页数:25 大小:321.77KB
下载 相关 举报
微机原理实验3汇编语言程序设计.docx_第1页
第1页 / 共25页
微机原理实验3汇编语言程序设计.docx_第2页
第2页 / 共25页
微机原理实验3汇编语言程序设计.docx_第3页
第3页 / 共25页
微机原理实验3汇编语言程序设计.docx_第4页
第4页 / 共25页
微机原理实验3汇编语言程序设计.docx_第5页
第5页 / 共25页
点击查看更多>>
下载资源
资源描述

微机原理实验3汇编语言程序设计.docx

《微机原理实验3汇编语言程序设计.docx》由会员分享,可在线阅读,更多相关《微机原理实验3汇编语言程序设计.docx(25页珍藏版)》请在冰豆网上搜索。

微机原理实验3汇编语言程序设计.docx

微机原理实验3汇编语言程序设计

微机原理实验3

实验设备:

LAB6000通用微控制器实验系统

实验用时10小时

一、实验内容:

汇编语言程序设计。

在了解8086/8088汇编语言后,编制并调试程序。

1.编制不恢复余数除法程序格式:

最高两位为符号位

2.按IEEE754格式编制32位浮点数与32位定点数相互转换程序子程序(两个子程序)

3.编制程序寻找100以内的质数,并从小到大排列。

4、编制8位(4字节)压缩BCD码加、减法程序。

5、编制8位(8字节)非压缩BCD码乘法和除法程序。

二、实验报告:

程序框图和源程序清单。

第一题必做,其余任选两个

第一题:

这道题可以按照老师所讲的不恢复余数除法的步骤,一步一步把书上的文字描述“翻译”成汇编语言。

1、执行第一次减法。

2、判断结果的正负,这里我们通过比较结果与0100h的大小关系来实现,结果大于等于0100h,说明结果小于0;结果小于0100h,说明结果大于0,最终会溢出,程序结束

3、如果上一次操作结果为正,则商1,被除数左移一位,减除数,跳转5

4、如果上一次操作结果为负,则商0,被除数左移一位,加除数,跳转5

5、判断上一次操作结果的正负

6、上面的第3,4,5步循环4次之后结束,如果最后一次操作结果小于0,则还要再左移一位,加除数。

这样就实现了8位除以4位的不恢复余数除法。

这道题的难点在于正确理解不恢复余数除法的步骤,和每一步的意义。

因为单纯翻译书上的内容很容易导致误解,只有真正理解了才能做出来。

这里比对一下自己最后梳理出来的1~6步,就会发现与书上所说的1~6步稍有不同,但是也是正确的。

程序流程图如下:

程序代码:

datasegment

Resultdb3dup(?

x2dw0021h

y2dw0040h

countdb0

signdw0h

dataends

;al保存被除数,bx第4~8位保存除数,ah,bh保存符号,即被除数为负,则ah=ffh,否则为0

;ax的第4~8位保存余数,dx的低4位保存商

codesegment

assumecs:

code,ds:

data

startprocnear

movax,data

movds,ax

movax,x2

movbx,y2

movcx,4

subax,bx

cmpax,0100h

jbjieshu

movdx,0;第一次为负

;shlax,1

shlax,1

addax,bx

bijiao:

cmpax,0100h

jbzheng;为正,跳转减法

;否则为负,执行加法

movsign,1

shldx,1;商0

addcount,1

cmpcount,4

jnbjieshu

shlax,1

addax,bx

jmpbijiao;进行下一次比较

zheng:

movsign,0

shldx,1

adddx,1

addcount,1

cmpcount,4

jnbjieshu

shlax,1

subax,bx

jmpbijiao

jieshu:

cmpax,0100h

jbendss

addax,bx

endss:

jmp$

codeends

endstart

第二题:

这道题的思路可以很快梳理清楚:

1、浮点数转定点数:

①确定符号,符号存入内存最高位,负数要取补②确定阶码③根据阶码值取相应数量的数构成整数部分(不要忘了浮点数中忽略了的最高位1)④剩余的部分是小数部分

2、定点数转浮点数:

①确定符号,存入内存最高位,负数要取补②确定阶码③忽略整数部分最高位1,其余部分存入内存④小数部分存入内存

思路即是这样。

难点在于处理的数据位数太多,超出了板子一次运算允许的最大范围。

这样就只能采取分步骤做,每做一步就把结果存入内存空间,之后内存空间左移若干位,为下一步骤存入数据腾出位置。

最终完成。

程序框图如下:

浮点数转定点数:

定点数转浮点数:

程序代码:

(先浮点转定点然后定点转浮点)

;将AX拆为三个BCD码,并存入Result开始的叁个单元

datasegment

;Resultdb3dup(?

xdd42c88000h

zhengshudb0;存整数部分,带符号,补码表示

xiaoshudb0;存小数部分,不带符号,原码表示

signdb0;保存符号

zhishudb0;保存阶码

countdb0;计数

tempdb0;

ctdb0;计数

dataends

codesegment

assumecs:

code,ds:

data

startprocnear

movax,data

movds,ax

movax,wordptrx;存低16位

movbx,42c8h;存高16位

shlbx,1

jbfu;负数,跳转到负数的处理部分

back:

;rclax,1;?

?

?

shlax,1

jbyi

jmpmain

yi:

addbx,1;程序结束后取消注释

jmpmain

main:

movzhishu,bh

shlbx,8

addbl,ah

shlax,8

subzhishu,7fh

movcl,zhishu

addbx,1

rolbx,cl

cmpsign,0

jaqufan

fuzhi:

movzhengshu,bl

movxiaoshu,bh

jmpnext

qufan:

;negbl

;subbh,1

;negbh

;addbl,80h

subah,bh

subal,bl

movbh,ah

movbl,al

jmpfuzhi

fu:

movsign,1

jmpback

next:

movax,0

movbx,0

movdx,0

movsign,0

moval,zhengshu

cmpzhengshu,80h

jbdayuling;低于跳转,是正数

movah,0ffh

movsign,1

movbx,0

subbx,ax

adddh,1

movax,bx

addah,80h

movbx,0

subbh,xiaoshu

shlax,1

jmphuiqu

dayuling:

movbh,xiaoshu;把取得的整数和小数部分分别存入段寄存器中

shlax,1

;jbfushu;判断是负数,把sign置为1

huiqu:

movcount,14

;movcount,6

jmpjishu

fushu:

movsign,1

jmphuiqu

jishu:

;rclal,1;从高到低一位一位的找,找到第一个1的时候,跳转,记下整数的位数

shlax,1

jbcunzheng

deccount

incct

jmpjishu

cunzheng:

addcount,7fh;求出偏移码

cmpsign,0

;jaqufu;取负值,高位为1

cmpcount,7h+7fh

;jataigao

movcl,count

movdl,cl;阶码存入dl

subcount,7fh

movcl,count

shldx,cl;dx左移,为整数部分存入做准备

;rolal,cl

rolax,cl

movtemp,al;

adddl,temp;整数最高7位(或少于7位)存入dx,之后ax就没有用了

movtemp,0

movcx,0

movax,0;到这里都还是对的

subct,7

movcl,ct

rolbx,cl;

movah,0ffh

shldx,cl;把dx剩下的最后几位腾出来,准备放入bx传递过来的数据

hehe:

shlal,1

addal,1

loophehe

subah,al

movtemp,bl

andtemp,al;把bl中由最高位移动过来的几位数保留下来

adddl,temp;然后存入dx剩下的空位中

andbl,ah;恢复bl

jmpjieshu;dx存高16位,bx存低16位

taigao:

shldx,7

rolax,7

movtemp,al

adddl,temp;整数最高7位存入dx,多出来的继续存入cx

movcl,temp-7

shrbx,cl;留出空间,把没存完的整数部分存进来

movtemp,ah

addbh,temp;整数部分全部存入,此时bx刚好保存了小数部分,完成

jmpjieshu

qufu:

adddh,1;把得到的浮点数编码存入dx中

jmpcunzheng

jieshu:

jmp$

codeends

endstart

第三题:

难度较小,只要用两层循环即可。

A循环是被检测数从1增加至100。

B循环是对每个被检测数,都要从2一直除到本身。

循环中不断地判定,如果出现了余数为0的情况,则跳出本次B,进入下一次A循环;如果直道一次B循环无跳出的执行完,都没有出现余数为0的情况,则这一个被检测数就是质数,把它存入内存单元。

程序框图:

程序代码:

;将AX拆为三个BCD码,并存入Result开始的叁个单元

datasegment

Resultdb30dup(?

xdd0c1c90000h

zhengshudb0;存整数部分,带符号,补码表示

xiaoshudb0;存小数部分,不带符号,原码表示

signdb0;保存符号

;zhishudb0;保存阶码

countdb0;计数

tempdb0;

ctdb1;计数

idb0;

dataends

codesegment

assumecs:

code,ds:

data

startprocnear

movax,data

movds,ax

movcx,99

movdx,0

movax,0

xunhuan:

incct;被检测的数

moval,ct;ct放在默认被除数的位置上

;jiance:

movi,2;i作除数,即因子

jiancea:

movbl,i

cmpbl,ct

jnbjixu;当i与ct相等时,认为找到了质数

divi

cmpah,0

jnaheshu;不高于跳转,表示余数为0,则是合数

movah,0

moval,ct;恢复做过除法的被检测数

addi,1

jmpjiancea;既没有发现余数为零的情况,i也比ct小,那么跳回检测分支的开头,重来

jixu:

;addcount,1

movbl,ct

mov[si],bl

;movresult,ct

addsi,1;不知道能不能像这样把地址的值直接加1,如果不行可以尝试对找到的质数计数count,然后每次存的时候用movresult+countct

;或许可以

heshu:

loopxunhuan;质数存在0400开始的连续空间里

 

jieshu:

jmp$

codeends

endstart

第四题:

本身句法结构不难,问题就是操作数位数过多,只能把操作数分割开,分别运算之后再组装在一起。

需要注意的是,分割开操作的时候要记录本位向高位的进位,同时考虑低位向本位的进位,这些数值,当一个部分的加法做完,转向下一个部分的加法时,一定要保存下来,带入下一次运算。

而减法则完全类似,把进位改为借位即可。

程序框图:

加法:

减法:

程序代码:

;将AX拆为三个BCD码,并存入Result开始的叁个单元

datasegment

Resultdb30hdup(?

x1dw0

x2dw0

;zhengshudb0;存整数部分,带符号,补码表示

;xiaoshudb0;存小数部分,不带符号,原码表示

signdb0;保存符号

;zhishudb0;保存阶码

countdb0;计数

tempdb0;

ctdb1;计数

idb0;

dataends

codesegment

assumecs:

code,ds:

data

startprocnear

movax,data

movds,ax

mov[si],5467h

mov[si+2],1234h

mov[si+10h],3716h

mov[si+12h],5438h

movax,0

movbx,0

movcx,4

jiafa:

jiancha:

addal,[si]

movbl,[si+10h]

addal,bl

;movcx,2

cmpal,9ah;看低8位是否对高8位有进位

jbjixu;低于跳转

subal,bl

addal,bl

addah,1;有进位,则高8位加1

movsign,1;把进位的标志也保存一下

jixu:

subal,bl

addal,bl

daa

mov[si+4],al

moval,ah

movah,0

addsi,1

loopjiancha

jianfa:

movcx,4

movax,0

movbx,0

;daa

;mov[si+2],al

;loopjiancha

subsi,4

mov[si+10h],5467h

mov[si+12h],1234h

mov[si],3716h

mov[si+2],5438h

jianchaa:

addal,[si]

movbl,[si+10h]

subal,bl;addal,bl

;movcx,2

cmpal,9ah;看低8位是否对高8位有借位

jbjixua;低于跳转

addal,bl;subal,bl

subal,bl;addal,bl

subah,1;addah,1;有借位,则高8位加1

movsign,1;把借位的标志也保存一下

jixua:

addal,bl;subal,bl

subal,bl;addal,bl

das

mov[si+8],al

moval,ah

movah,0

addsi,1

loopjianchaa

jmp$

codeends

endstart

第五题:

我只做了乘法部分。

仍然是面临操作数过大的问题。

我采用的是模拟手工竖式运算的方式,先取被乘数最低位,与乘数每一位分别相乘(考虑乘法进位),得到一行数;然后取被乘数次低位,与乘数每一位分别相乘,得到一行数,这一行比上一行高了一位;随后按照类似的方法,得到了8行数;最后,按竖式加法把每一列都按照BCD码的加法加起来(注意进位),得到的第9行数,就是乘法的结果。

程序框图:

(省略了最后的竖式加法部分,因为它就是BCD码加法运算,比较简单)

程序代码:

 

datasegment

Resultdb160hdup(?

x1dw0

x2dw0

signdb0;保存符号

countdb0;计数

tempdb0;

ctdw0;计数

idb0;

dataends

codesegment

assumecs:

code,ds:

data

startprocnear

movax,data

movds,ax

mov[si],0302h;low

mov[si+2],0606h

mov[si+4],0206h

mov[si+6],0701h;high

mov[di],0503h;low

mov[di+2h],0304h

mov[di+4h],0607h

mov[di+6h],0403h;high到这里没有问题

movcx,8

xiaocheng:

movax,0

movbx,0

addal,[si];之所以用add是因为难免低位会向高位进位,采用add的形式就可以把进位也存进来了

movbl,[di]

mulbl;此后直到下一个循环开始前bl不再参与这次乘法运算,可以再给它安排新的任务

aam

addsi,ct

addsi,di

add[si+11h],ah;乘法进位先存入结果的高一位

movah,0;然后把ah置0

movbl,[si+10h];先把结果的本位取出来,与al相加后再存回去,以免忽略

;结果与之前的进位相加后又产生的加法进位

addal,bl

aaa;非压缩BCD码的加法调整,调整后,ah中存放的是加法进位,

;这里加法进位是能直接加到结果高一位里去的,因为加法进位和乘法进位相加后不会再产生更高的进位了

add[si+11h],ah

mov[si+10h],al

;add[si+10h],al;本位存入结果的本位,这里又要考虑加法进位

subsi,ct

subsi,di

;moval,ah

incsi

cmpsi,8

jbxiaocheng

incdi

subsi,8

addct,10h

loopxiaocheng;理论上说到这里按竖式做的乘法已经一行一行的存进si起始的单元里了

subdi,8

adddi,10h

movax,0

movbx,0;到这里都是对的

movcx,8;下一个循环是要把竖式的值加起来

addsi,10h

movct,0

moval,[si]

xiaojiafa:

addsi,10h

movbl,[si]

addal,bl

aaa

loopxiaojiafa

movcx,8

mov[si],al

add[si+1],ah

subsi,80h

incsi

movax,0

movbx,0

moval,[si]

cmpct,16

jbxiaojiafa

jmp$

codeends

endstart

实验感想:

1、要敢于尝试。

开始接触的时候完全没有感觉。

它与C语言的编程风格迥然不同,很多地址空间是受限制的,比如不能直接读取、位数有限、有特定的功能,还有就是语言与自然语言差别很大。

这些陌生的概念积压在一起的时候就让人摸不着头脑。

借鉴以前学C语言的时候,我是从最短的开始,把书上的例程一个一个抄在编译环境里,然后单步执行,看每一步的变化。

这种方法既让我熟悉了每种功能语句的写法,也知道了语句的含义,看起来笨,实际上学得很快。

这次尝试我也是用了同样的办法。

抄了几个以后就开始凭着感觉写几个语句,然后执行以下,达到预期以后做个标记再往下写,慢慢的程序就写出来了。

2、细致。

我个人最容易出错的地方是搞不懂循环的次数,就比如说我要执行8次循环,cx的值该设为7还是8,这个问题我每次都要花点时间搞搞清楚。

做作业的时候也是经常因为多做了一次循环导致结果出错。

不过好处就是每次程序出错的时候我都知道该先从哪些地方找错误。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 求职职场 > 简历

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1