汇编语言程序设计步骤:1、 分析问题,抽象出描述问题的数据模型 2、 确定问题的算法思想 3、 画出流程图或结构图 4、 分配存储器和工作单元(寄存器) 5、 逐条编写程序 6、 静态检查,上机调试 例:编程查找考生的最高分,假设所有考生分数已存入计算机内存1、 分析问题 根据条件、特点、规律 →数学模型 本例分数已给定为0~200之间的整数集合(考虑加试分) ,记为{S},找max{S}(注:简单问题不一定写数学模型) 2、 确定算法思想 最好利用现成算法和程序设计方法,若无,则需根据实践经验总结算法思想如本例,从成绩单第一分数往下看,边看边比较,记住较高分,舍弃较低分,直至看完,最高分存于 脑中归纳算法思想:建立数据指针并指向数据区首地址将第一数取入寄存器(如AL) ,与下一数比较,若下一数大则将其取入寄存器,否则调整指针,再与下一数比较,重复上述 直至比较完毕,寄存器中即最高分读分数用MOV指令,比较用CMP指令,分析判断用条件转移指令3、 画流程图或结构图 有逻辑流程、算法流程、程序流程等,复杂问题需画模块结构本例简单,只画出程序 流程图(用模块化结构的N-S流程图表示) :本例的N-S流程图 图中初始化包括:设一个计数器,将分数个数减一后送计数器,每比较一次减一,至 零查找结束;建立一个指针指向数据区开始 初始化 取第一数到寄存器 与下一数比较 下一数大是 否 取大数到寄存器 修改指针,计数次数减一 返回到循环体开始,直到计数次数为0退出循环 结束 4、 分配存储器空间和工作单元(寄存器) 定义数据段、堆栈段、代码段等工作单元一般用寄存器本例:分数放数据段,建100 字节堆栈空间,BX作数据指针,CX作计数器,AL放最高分5、 逐条编写程序 DATA SEGMENT FEN DB 85,90,60,75,87,35,80,78,96,82…… ;存分数 MAX DB ;存最高分 DATA ENDS STACK SEGMENT PARA STACK ‘STACK’ DB 100 DUP() ;100字节堆栈 STACK ENDS CODE SEGMENT ASSUME CS:CODE,DS:DATA,SS:STACK START PROC FAR PUSH DS MOV AX,0 PUSH AX ;为了返回DOS MOV AX,DATA MOV DS,AX ;置数据段寄存器 MOV BX,OFFSET FEN ;置数据指针 MOV CX,MAX-FEN ;置计数器初值 DEC CX ;N个分数比较N-1次 MOV AL,[BX] ;取第一个分数 LOP:INC BX ;调整指针 CMP AL,[BX] ;与下一数比较 JAE NEXT ;大于等于则转 MOV AL,[BX] ;否则取下一数 NEXT:LOOP LOP ;计数器减一,;不为零转LOP MOV MAX,AL ;存放最高分 RET ;返回DOS START ENDP CODE ENDS END START 6、 静态检查,上机调试 选用指令尽量字节少,使其执行速度快易错处应重点查,如比较次数、转移条件等确信无错后方可上机调试
我就说一下该程序的功能:
在数据段BLOCK变量下存放了二十个数,占据二十个字单元;
把第一个数赋给AX寄存器然后和下一个数比较,如果AX中的数大,就再和下下一个数比较;如果AX中的数较小,就把大数装入AX再和下个数比较。累计比较十九次,最后AX中装的就是最大的那个数,将此数传递给MAX变量。
你可能刚开始学汇编觉得难,没关系,先搞懂CPU、存储器、I/O以及总线之间的关系,再记住几个常用的CPU寄存器,至于汇编程序大部分时间都是装(MOV)来装去的,多读一些程序就熟了。
祝你好运。
code segment ;段定义开始
assume cs:code ;code段指定给CSCS段为代码段
start: ;程序开始执行的位置(由end start指定)
begin:mov ah,1 ;INT 21H的功能号该功能号为: 键盘输入功能
int 21h ;键盘输入
cmp al,'a' ;AL=键盘输入的符号,它与'a'进行比较
JB stop ;如果AL<'a',则转到stop
cmp al,'z' ;AL=键盘输入的符号,它与'z'进行比较
ja stop ;如果AL>'z',则转到stop
sub al,20h ;小写字母改为大写字母
mov dl,al ;AL赋给DL,为了显示
mov ah,2 ;INT 21H的功能号该功能号为: 显示DL的值
int 21h ;显示DL的值
jmp begin ;循环,即输入下一个符号
stop: ;如果键盘输入的不是小写字母,则跳到这里
mov ah,4ch ;INT 21H的功能号该功能号为: 退出程序
int 21h ;退出程序
code ends ;段定义块结束
end start ;指定本程序从strat开始执行
真累啊不知你满意否
这个程序很简单
org 000bh
ljmp itm0 定时器t0中断入口
main: clr P10 p10低电平
lcall dly500 调用延迟程序
cpl P10 p10高电平
lcall dly500 调用延迟
ljmp main 主程序,实现是p10口高低电平转换
dly500: 延时程序
mov tmod,#0001h
mov tl0,#0b0h
mov th0,#3ch 定时器t0初始化
setb ea 开总中断
setb et0 开t0中断
setb tr0 开始定时器计数
mov r0,#10 默认循环10次
loop: mov a,r0 a赋值10
jz return 判断a是否为零 为零跳转到return
ljmp loop 跳转loop
itm0: 中断运行程序
mov tl0,#0b0h
mov th0,#3ch 初始化定时器
dec r0 r0减一
reti 中断返回
仔细读一读就能懂了 好运!
虽然没有楼上动作快,但既然也做了就发上来参考吧,应该比楼上的更具体写,比如P15干嘛啊。 :)
__________________________________________________________________
整体描述:同时在P10 和 P11输出反相的占空可调的方波
占空比调整通过修改变量M 来设定,变量AS用来做内部循环量,范围0-M
P15使用闪烁的方式来显示对于M设定的占空比值的非法告警
调整占空比设定M通过int0 和P12来 进行加一和减一的设定 ,通过int1 和P12来 进行加五和减五的设定
设定的M值通过连接在P0,P2口的两个LED来显示,方式10进制单位显示
COUNT EQU 30H //没用的变量
AS EQU 30H //timer1内占空比计数
M EQU 35H //占空比计数上限设定
ORG 0000H
LJMP START
ORG 0003H //int0中断服务入口 占空比1步进
LJMP INT00
ORG 0013H //int1中断服务入口 占空比5步进
LJMP INT11
START: SETB EX0 //初始化开始
SETB PX0
SETB IT0
SETB EX1
CLR PX1
SETB IT1
SETB EA
CLR P15 //P15显示设定占空比数字非法时闪烁告警
MOV TMOD,#21H //使用timer0 模式1和timer1 模式2
MOV TH1,#38H //timer1做占空部分控制,即高低电平时间控制
MOV TH0,#0B1H //timer0做方波周期
MOV TL0,#0E0H
SETB TR0
SETB TR1
MOV DPTR,#TABLE //LED段码地址
MOV M,#50 //占空比上限初值
MOV P0,#3FH //占空比10进低位 LED段码
MOV P2,#6DH //占空比10进高位 LED段码
MOV AS,#0 //占空比计数变量
TOP:SETB TR1 //新的一个方波周期从这里开始
SETB P10 //P10和P11分别输出反相的等周期方波
CLR P11 //
MOV TH0,#0B1H //timer0计数值、即方波周期值设定
MOV TL0,#0E0H
MOV AS,#0 //高电平时间计数变量初值每个timer1溢出加一(最大等于M)
MOV B,#10 //没用
MOV A,M
MOV B,#100
DIV AB
JZ TIME1 //如果设定的M值在01-99(可以理解为可接受的值,占空比最少1:99最多99:1)
MOV B,#10
CLERK:SETB P15 //设定的占空比值非法,则闪烁P15告警
LCALL DELAY
CLR P15
LCALL DELAY
SETB P15
LCALL DELAY
CLR P15
MOV M,#50 //自动重新设定默认占空比
LCALL SHOW //LED显示M,即当前设定占空比的值
LJMP TOP //重新 开始新懂得方波周期
TIME1:JBC TF1,NEXT //等待timer1 溢出标志
SJMP TIME1
NEXT:INC AS //每次溢出变量AS加一,
MOV A,M
CJNE A,AS,TIME1 //直到AS=M ,即占空计数达到,
CLR P10 //波形反相
SETB P11
CLR TR1 //关闭timer1,波形在timer0控制的一个周期内不再变化
TIME0:JBC TF0,TOP
SJMP TIME0 //timer0溢出,开始下一个周期波形
INT00:JNB P12,LOOP1 //外部中断0中断处理
INC M //当int0 为低电平且P12为高则M增加1,每次机器响应int0都加一,直到int0消失
LCALL SHOW //LED显示M,即当前设定占空比的值
RETI
LOOP1:DEC M //当int0 为低电平且P12为低则M减1,每次机器响应int0都减一,直到int0消失
LCALL SHOW //LED显示M
RETI
INT11:JNB P12,LOOP //外部中断1中断处理
MOV A,M
ADD A,#5 //当int1 为低电平且P12为高则M增加5,每次机器响应int0都加五,直到int0消失
MOV M,A
LCALL SHOW //LED显示M
RETI
LOOP:MOV A,M
SUBB A,#5 //当int1 为低电平且P12为高则M减少5,每次机器响应int0都减五,直到int0消失
MOV M,A
LCALL SHOW //LED显示M
RETI
SHOW:MOV A,M //M /10 AB 内分别是商和余数
MOV B,#10
DIV AB
MOVC A,@A+DPTR //查表显示余数
MOV P2,A
MOV A,B
MOVC A,@A+DPTR //查表显示商
MOV P0,A
MOV B,#10 //没用
RET
DELAY:MOV R6,#0FFH //延时函数
DEY1:MOV R7,#0FFH
DEY2:MOV R5,#3
DJNZ R5,$
DJNZ R7,DEY2
DJNZ R6,DEY1
RET //延时结束
TABLE:DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH //LED段码表
END
首先得了解汇编指令吧,其次得用机器的逻辑思考问题,明白其中的存储、累加、判断、转移等概念。
比如,1+2++100这样的问题,虽然我们可以给出公式计算,但机器并不知道,它只能知道,而且只能每次做一个加法,而且鉴于CPU的架构不能存所有的这些数值-如果这些数量不定的话更复杂,比如这些数是放在一个内存区域的,内存区域约定如下:第一个数表示总共有多少个数,后面是相应的数据,在这些数没有规律时是不能用公式的。
另外,许多CPU约定只有一个累加器(同时也是一个寄存器,假设它是寄存器AX),它允许从内存读一个数(MOV或者LD指令),只能进行内存数据加法(ADD [地址])。
于是我们只能这样,首先设置指针寄存器BX:
start: mov BX,#地址 ; 设置内存区域起始地址,保存在BX中
mov CX,[BX]; 取出总数到CX中,假设CX可以做简单递增或递减
dec CX ; 预减一次计数器,因为加法只需做CX-1次
inc BX
mov AX, [BX]; 取出数据
loop: inc BX ;递增BX,使之指向真实数据
ADD AX,[BX];用下一数据进行累加,并将结果保存在AX中
dec CX ;假定这个减法会影响标志位ZF
JNZ loop ;如果没有减到0就继续loop到这里之间的 *** 作
mov [BX], AX; 保存累加结果到数据区的尾部
HALT ; 停机
可以看出,上述代码并不能告诉我具体结果是多少,除非我们通过工具去访问这一内存区域,于是一个系统会设计出来专门让我们进行基本的输入输出,把计算机的内部情况甚至内存情况通过I/O口送出来,这些IO设备,比如键盘负责接收我们的机器指令(可以是汇编结果,也可以是高级语言产生的二进制指令和数据流),把结果输出到打印机或者CRT这样的输出设备上(通常映射为端口,IO PORT)。这就是BIOS完成的工作,如int 8负责时钟,int 10负责屏幕,int 16负责键盘等等。更进一步,可以进一步封装称DOS调用,如int 21负责基本的输入输出包括文件 *** 作等等。WINDOWS等 *** 作系统则通过驱动层进行多级抽象提供 *** 作界面给编程人员,编程人员再进一步封装出对话框或全屏文字菜单或流式(行式 *** 作) *** 作界面给最终用户。
以上就是关于汇编语言程序设计步骤 有那几步全部的内容,包括:汇编语言程序设计步骤 有那几步、给下面的汇编语言源程序加注释,分析程序的功能,画出程序流程图。、汇编程序解释等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)