




已阅读5页,还剩50页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
glut_c 2013-08 j.cb,1,3.3. 程序的基本结构,最基本的程序结构:顺序结构、分支结构、循环结构。,子程序、中断服务程序是一种特殊的程序,它们也是由以上三种基本结构构成的。,glut_c 2013-08 j.cb,2,3.3.1 简单程序设计,例:编写程序将字变量w中的无符号数w=65525除以8,将商保存在字变量qout中,将余数保存在字节变量rema中。 算法分析: 可以使用除法指令,也可以使用右移三位实现除以8的运算。 65525 0fff5h 1111 1111 1111 0101b,(1)右移3位,移出的三位就是余数,剩余的就是商。 余数的保留:可以选择两种方法,glut_c 2013-08 j.cb,3,glut_c 2013-08 j.cb,4,使用伪指令定义w、qout、rema三个内存单元,w、qout为16位,rema为8位。,这里的结束是结束应用程序,返回操作系统。 可以使用int 21h的 4ch号功能调用返回操作系统 mov ah,4ch int 21h,glut_c 2013-08 j.cb,5,data segment data w dw 65525 qout dw ? rema db ? data ends code segment code assume cs:code, ds:data start:mov ax,data ;取数据段开始地址 mov ds,ax ;数据段开始地址送数据段基址寄存器 mov ax,w ;从存储器取出ds:wax mov bl,0 ;余数寄存器清0 sar ax,1 ;算术右移1位,符号不变,w最低位进入c rcr bl,1 ;带进位循环右移1位,c进入bl最高位 sar ax,1 ;算术右移1位,符号不变,w次低位进入c rcr bl,1 ;带进位循环右移1位 sar ax,1 ;算术右移1位,符号不变,w次低位进入c rcr bl,1 ;带进位循环右移1位,余数在bl高3位 mov cl,5,数据段结束,代码段开始,数据段开始,glut_c 2013-08 j.cb,6,sar bl,cl ;余数右移5位,将其移到bl低3位 mov qout,ax ;保存商 mov rema,bl ;保存余数 mov ah, 4ch int 21h code ends end,本程序是返回操作系统,代码段结束,汇编源程序结束,glut_c 2013-08 j.cb,7,还有就是: w直接取低3位作为余数 然后w右移3位得到商,开始,定义w、qout、rema,axw ,rema 7 rema rema and al,ax右移3位 qout ax,开始,ax右移3位: mov cl ,3 sar ax , cl 注意:如果是带符号数,就要用算术右移sar,不要用逻辑右移shr 对于无符号数,则可用sar或shr 这里选用sar,glut_c 2013-08 j.cb,8, mov ax,w ;从变量w取数据 mov rema, 7 ;余数变量remap赋值00000111b and rema,al ;余数是al的 最低3位, mov cl,3 ; sar ax, cl ;算术右移3位,符号不变,ax中得到商 mov qout,ax ;保存商 mov ah, 4ch int 21h 该程序结果相同,但程序代码简单了,执行速度也快了,glut_c 2013-08 j.cb,9,(2) 使用除法指令 div src 注意:对于8086处理器 为了商是字数据, 被除数32位:dxax(dx0,axw) 除数16位 bx8 div bx 商在ax, 余数在dx,对于本次运算,余数为字节数据,实际上只有dl有效,.data w dw 65525 qout dw ? rema db ? .code mov ax, data mov ds, ax mov dx,0 mov ax,w mov bx,8 div bx mov qout, ax mov rema, dl mov ah, 4ch int 21h end,如果是带符号数,应该使用符号扩展指令cwd和带符号除法指令idiv 由于题目指定是无符号数,这里可以将高16位扩展为0,用div除法指令,glut_c 2013-08 j.cb,10,例 将ax中的3位bcd数转换为二进制数存入字节变量sb中(ax中的数大于0,小于255),每位十进制用一个8421编码(自然二进制编码)表示(即每一位十进制数都是用二进制表示) 十进制数的展开表达式,3位bcd码,glut_c 2013-08 j.cb,11,主要部分程序流程图,al=al+ah,al=al*ch,ahbl,al=百位*10 既执行al=al*ch,al=bl and 0fh al=al+bl,因百位*10不会大于255,ah=0,可以使用 ah右移4位,高位补0得到十位数,alsb,保留各位十位到bl,取百位到al alah,ch 10,cl=4,ah=bl,ah右移4位得到十位,由于题目给出不大于255,因此最后一次乘10加个位也只是一个字节相加,glut_c 2013-08 j.cb,12,m0v ch,10 mov cl,4 mov bl,al ;暂存十位和个位到bl, mov al,ah ; 百位存入al中 mul ch ;百位10ax mov ah,bl shr ah,cl ;取十位 add al,ah ;百位10 + 十位al mul ch ;(百位10 + 十位)10 ax and bl,0fh ;取个位 add al,bl ;(百位10 + 十位)10 +个位al ;约定结果不大于255 mov sb,al ; alsb, 如果没有明确结果不大于255,则需要考虑16位结果,glut_c 2013-08 j.cb,13,0999的bcd数转换为二进制,主要部分程序流程图,al取百位,ax百位*10,ah取十位,百位*10+十位 al=al+ah,ax=al*10,bl=bl and 0fh ax=ax+bx,因百位*10不会大于255,ah=0,可以使用 ah右移4位,高位补0得到十位数,axsb,sb应该是字操作数(16位),bh要清0,ax为000999之间的bcd数,glut_c 2013-08 j.cb,14,m0v ch,10 mov cl,4 mov bl,al ;暂存十位和个位到bl, mov al,ah ; 百位存入al中 mul ch ;百位10ax mov ah,bl shr ah,cl ;取十位 add al,ah ;百位10 + 十位al mul ch ;(百位10 + 十位)10 ax and bl,0fh ;取个位 mov bx,0 ; bh=0, add ax,bx ;(百位10 + 十位)10 +个位sb ;最后结果为16位数,不能简单+低8位 mov sb,ax ;axsb,glut_c 2013-08 j.cb,15,简单程序设计例,下面再看几个补充的例题。 例 :将存储器单元dat1中保存的一个组合bcd数转换成两个对应ascii码值,并存入dat2开始的两个单元,低位在前,高位在后。,glut_c 2013-08 j.cb,16,bcd码转换成ascii码数据: 非压缩bcd数据在高半字节+3.例如数字5 5:0000 0101 0011 0101,得到的结果是相同的。都是在高半字节加3。,glut_c 2013-08 j.cb,17,该问题算法就很简单: 从dat1取出bcd数据,先将高4位清“0”,与30h相加或进行逻辑或,存入dat2,再取出数据,将数据逻辑右移4位(高位bcd数移到低4位,高4位变“0”,再与30h相加(或进行逻辑或),存入dat2+1单元。 程序流程图:,glut_c 2013-08 j.cb,18,程序流程图,程序代码,data segment dat1 db 34h ;待转换的数 dat2 db ?,? data ends code segment assume cs:code, ds:data stara: mov ax, data mov ds, ax ;送段地址 lea si,dat1 lea di,dat2 mov al,si and al, 0fh add al,30h mov di,al mov al,si,显示: mov dl,al mov ah,02h int 21h,glut_c 2013-08 j.cb,19,mov cl,4 shr al,cl orl al, 30h mov di+1, al mov ah,4ch int 21h code ends end start,如果要送到屏幕显示,则将转换结果先送dl,02送ah,调用dos功能。 送ascii字符显示的系统调用: 功能ah=02h, 需要显示的字符ascii码dl , 执行 int 21h,显示: mov dl,al mov ah,02h int 21h,ah=4ch功能调用。功能是结束本程序,返回dos,glut_c 2013-08 j.cb,20,再看一个顺序程序: 编写一个计算z=(x2-3y)/2的程序,x,y为单字节正整数,z用2字节保存。 这是一个算术运算程序,算法设计: 首先计算 x2=x*x, 暂存该结果, 其次计算 3*y, 第三步计算 x2-3*y 第四步计算 (x2-3y)/2。该步使用算术右移实现除2运算,比用除法指令执行速度快。 依据该算法,可以画出程序流程框图。,glut_c 2013-08 j.cb,21,x2的计算, 可以分解为,3*y的计算, 可以分解为,glut_c 2013-08 j.cb,22,;数据段定义 data segment x db 25 y db 32 z dw ? data ends ;代码段开始 code segment assume cs:code, ds:data expre proc far ;过程定义,远过程 start: push ds ;ds:00保存的是一条返回 sub ax,ax ;dos 指令。 push ax ;这里,将返回dos的地址 ;压入堆栈 mov ax,data,操作系统会自动在ds:00处安排一条返回操作系统的指令,故子程序开始处向堆栈中压入 ds:00 执行ret指令,则就是转到ds:00返回dos,glut_c 2013-08 j.cb,23,mov ds,ax ;数据段首地址(基地址) mov al , x ;取变量x mov bl,al mul bl ;x*x=x2 mov bx,ax mov al , y ;取变量y mov ah,0 ;正整数,高字节直接扩展0 mov cx,ax add ax ,cx ;2y add ax, cx ;3y xchg ax, bx sub ax ,bx ;x2-3y shr ax ,1 ; 右移一位 /2 mov z , ax ret ;将ds:00弹出到cs:ip expre endp ;过程定义结束 code ends end start,ret 指令,转到ds:00,对于exe格式程序,它是一条返回dos的指令。,glut_c 2013-08 j.cb,24,;数据段定义 data segment x db 25 y db 32 z dw ? data ends ;代码段开始 code segment assume cs:code, ds:data mov ax , data mov ds , ax mov al , x mov bl , al,可以使用常规返回dos方法 int 21h的4ch功能调用,glut_c 2013-08 j.cb,25,mul bl ;x*x=x2 mov bx , ax mov al , y ;y mov ah , 0 mov cx , ax add ax , cx ;2y add ax , cx ;3y xchg ax , bx sub ax , bx ;x2-3y shr ax ,1 ; 右移一位 /2 mov z , ax mov ah , 4ch int 21h expre endp ;过程定义结束 code ends end start,用int 21 的4ch号功能调用返回dos。,glut_c 2013-08 j.cb,26,例 bcd加法程序,例如:已知字变量w1、w2分别存放两个非压缩的bcd数,编写程序求两数之和,并将结果存入sum字变量中。 注意:w!,w2为2为字变量(2字节)压缩bcd数,0099,它们的和则可能为3位bcd数,故sum应该定义3个字节(用db定义三个字节)。 计算机内部只有二进制运算指令,对于bcd数运算,是十进制数,用二进制运算指令运算,需要进行调整。 加法、减法、乘法在运算后进行调整 除法在运算前先进行调整。 只有字节运算才能进行调整 非压缩bcd数加法调整 aaa(压缩bcd数加法用daa),glut_c 2013-08 j.cb,27,压缩bcd加法后,用daa调整 非压缩bcd加法后,用aaa调整 压缩bcd减法后,用das调整 非压缩bcd加法后,用aas调整 压缩bcd加法后,用aam调整 (压缩的bcd乘法,不能调整) 除法指令前用aad调整(存放在ax中的两位非压缩bcd数),将sum+2清0,然后进行带进位的循环左移,就可将cy移进sum+2最低位,其余位=0,glut_c 2013-08 j.cb,28,例如:0809+0607=01 05 06,程序段如下:,data segment w1 dw 0809h w2 dw 06078h sum db 3 dup(0) data ends code segment assume cs:code,ds:data,ss:stack mov ax,data mov ds,ax ; mov al,byte ptr w1 ;取第一个数,al09h add al,byte ptr w2 ; al09h+07=10h,af=1 aaa ;al06h,产生cf=1 mov sum,al ;保存个位,进位信号在cf mov al,byte ptr w1+1 ;al08h,glut_c 2013-08 j.cb,29,adc al,byte ptr w2+1 ; al0fh, cf=0 aaa ;al05h, cf=1 mov sum+1,al ;存百位和千位 mov sum+2,0 ;处理向百位的进位,先将sum+2 rcl um+2,1 ;清0,然后用带进位循环左移指 ;令将进位位移到sum+2最低位 实际上,在sum定义时,已经初始化为0,程序中可以不清0 定义的变量w1,w2,sum在汇编语言源程序中可以直接使用,汇编程序在对源程序进行汇编时,可以识别是从变量所存放的存储器中取出数据实际上就是汇编程直接寻址指令 mov al,w1, 为了书写简单,我们直接写成 mov al,w1.,glut_c 2013-08 j.cb,30,以上例子,有一些只给出了实现所要求功能的核心部分分代码,没有给出段定义的完整部分。 有一些则给出了包含段定义的完整代码; 段定义的格式是相似的,可以参照教材上的例子和前面的段定义例子编写。 教材上还有一些顺序程序的例子,由于时间关系,就不一一列举了。,glut_c 2013-08 j.cb,31,顺序程序的结构简单,但实际程序设计中,往往需要对某些条件进行判断,依据不同的条件执行不同的分支,这样,顺序程序将不能满足要求。,glut_c 2013-08 j.cb,32,3.3.2 分支程序的设计,就是利用cpu的条件转移指令,通过判断某个标志为的状态,控制程序的执行过程。,glut_c 2013-08 j.cb,33,二分支结构,分支结构,判断,b,n,y,abc1,abc2,glut_c 2013-08 j.cb,34,多分支结构,glut_c 2013-08 j.cb,35,也可以按照条件编码实现多分枝转移,例如段内间接转移指令 jmp reg 转移到cs:ax jmp word ptr mem 转移到cs:mem,k是一个不小于2的整数。,glut_c 2013-08 j.cb,36,我们还是通过实例来讨论。 例:内存单元m中有一个16位的带符号数,求它的绝对值,并将结果放回原处。 算法:求一个数的绝对值时,如果是正数,绝对值不变,如果是负数,则求它的机器负数(连同符号位一起每位取反,最低位+1,就是使用neg指令)。 有了算法,可以画出程序流程图。,glut_c 2013-08 j.cb,37,转移目的指令给出标号(符号地址),n_data,负数,该标号为了阅读程序方便,判断数据的符号,在x86中就是判断sf标志位,数据传送指令不改变标志位,因此用一条逻辑运算指令 orl ax,ax, 它不改变ax的值,但设置标志位sf,glut_c 2013-08 j.cb,38,data segment m dw 789ah ;可以任意输入一个数 data ends code segment assume cs:code2,ds:data2 start: mov ax,data mov ds,ax lea si, m ;mov si,offset m mov ax,si orl ax,ax ;and ax,ax jns done ;符号为sf=0转移到done n_data: neg ax ;负数,利用neg指令求负 done: mov si,ax mov ah,4ch int 21h code ends end,glut_c 2013-08 j.cb,39,多分支程序,对分支程序,可以由这种2分支程序构成。,glut_c 2013-08 j.cb,40,计算函数的程序,x是十六位长度字数据,算法分析:取出数据x,判断它的符号,首先判断是否=0,如果不是,则是负数,y=-1,如果是,还须再次判断是否等于0。 程序流程框图为:,glut_c 2013-08 j.cb,41,glut_c 2013-08 j.cb,42,data segment x dw -8 y db ? data ends code segment assume cs:code3, ds:data3 start: mov ax, data3 ;设置段基址 mov ds, ax lea si, x ;取偏移地址 mov ax, si and ax,ax,glut_c 2013-08 j.cb,43,jns lp1 ;sf=0,转到lp1 lp0: mov y,0ffh ;=0,继续判断, ;=0转到lp3 lp2: mov y, 01h ;x0时, y=1 ljmp end1 lp3: mov y,00h ;x=0时,y=0 end1: mov ah,4ch ;返回操作系统 int 21h code ends end start,glut_c 2013-08 j.cb,44,教材上有一个例子,,算法分析:取出数据x,y,异或,判断符号, sf=1,表明符号异号z=0; sf=0,表明符号相同,判断是否x0,是,z=1,否z=-1。,glut_c 2013-08 j.cb,45,多分支的另一种实现方法,除了用二分支指令实现多分支外,还可以用以下指令实现: jmp reg ; jmp word ptr mem 例如,我们要依据al中的低4位数据(015)不同,分别转移到对应的分支去执行,每个分支约定占用200字节空间。 这类指令应用方法如下:,glut_c 2013-08 j.cb,46,anl al, 0fh mov bl,100 mul bl mov ax, fun0 ; jmp ax fun0: . org fun0+100 fun1: ;fun1-fun0=100 ;可以用定位伪指令确定每个 ;分支相距的距离 org fun14+100 ; 只要保证这段空间能存下 fun15: ; 这段代码。,也可以是一个转移表,利用远转移指令转到各处理程序,这样各功能分值的距离就比较小,而且相距的字节数也相同。,glut_c 2013-08 j.cb,47,例3.9 从键盘上键入2位十六进制数将其拼合成一个字节存入字节变量sb中。 data segment ibuf db 3,0,3 dup(0) sb db 0 data ends code segment assume cs:code,ds:data mov ax,data mov ds,ax mov dx, offset ibuf ;键入2位十六进制数 mov ah, 10 int 21h mov ax, word ptr ibuf+2 ;键入字符从+2单元开始,取出送ax sub ax, 3030h ;字符变为十六进制数 cmp al,0ah jb lnsub7 ;09,ascii-30h就是它对应的hex值 sub al,7 ;af,ascii-37h就是它对应的hex值,glut_c 2013-08 j.cb,48,lnsub7:cmp ah,0ah jb lnsub7 sub ah,7 hnsub7:mov cl, 4 ;将ax中的数拼合成一个字节 shl al ,cl or al, ah mov sb,al mov ah,4ch int 21h code ends end,glut_c 2013-08 j.cb,49,例3.10 某工厂的产品有8种不同的加工处理程序p0p7,根据键盘输入,做不同的处理,若是07以外的键,则退出加工处理,此例可以用两种方法实现: 一种是用逐一比较判断,逐次比较转移实现二叉分支、整体上实现多分支; 另一种是跳转表法,直接实现多分支.,glut_c 2013-08 j.cb,50,方法一逐一比较法.简单,条理清楚,易于实现,但转移范围只能是:128127 data segment input db input( 07): $ data ends code segment mov ax, data mov ds,ax mov dx , offset input ;显示提示符 mov ah , 9 ;09号功能是显示字符串,$是字符串结束符 int 21h ; mov ah , 1 ;等待键入一个字符到al, int 21h cmp al , 0 ;为0字符则转p0 je p0 cmp al , 1 ;为1字符则转p1 je p1,glut_c 2013-08 j.cb,51,cmp al ,2 je p2 cmp al ,3 je p3 cmp al ,4 je p4 cmp al ,5 j
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 第三章 物态变化单元测试卷 (含答案)2025-2026学年人教版(2024)八年级物理上册
- 郑州荥阳市公益性岗位人员招聘考试真题2024
- 2025年山东省黄河三角洲农业高新技术产业示范区山东省师范类高校学生从业技能大赛一、二等奖获得者(13人)模拟试卷及一套答案详解
- 2025年智能交通系统与城市拥堵治理
- 2025年海洋能源利用:海水提铀吸附材料技术创新研究
- 2025年海洋能发电技术国际合作与市场拓展报告
- 2025湖北襄阳市枣阳市招聘事业单位人员206人考前自测高频考点模拟试题及答案详解(全优)
- 2025年春季中国邮政储蓄银行云南省分行校园招聘考前自测高频考点模拟试题附答案详解(模拟题)
- 2025春季陕汽控股校园招聘考前自测高频考点模拟试题及答案详解(考点梳理)
- 2025北京大学电子学院招聘劳动合同制1人考前自测高频考点模拟试题及一套完整答案详解
- 广东省2025年度初级注册安全工程师职业资格考试金属非金属矿山安全复习题及答案
- 湖南安全员c3考试试题及答案
- 2025年中学生心理健康测试题及答案
- 二年级防溺水教案
- 后厨设备安全操作培训课件
- 妊娠期高血压用药
- 第十三章泌尿男性疾病
- 我不是完美小孩
- 【超星尔雅学习通】海上丝绸之路网课章节答案
- 有趣的化学启蒙课
- 轻钢龙骨隔断墙施工合同协议书
评论
0/150
提交评论