微机原理作业1

虽然对于微机原理与接口技术这门课已经比较摆了,但还是记录一下学的一点东西。

(汇编代码都是本来就有的)

例1: 在屏幕上依次显示“1”“2”“3”“A” “B” “C”个字符。

;定义数据段
DATA  SEGMENT
STR  DB ‘123ABC’
DATA  ENDS

CODE  SEGMENT
   ASSUME CS:CODE,DS:DATA
START:   MOV AX, DATA
         MOV DS,AX              ;初始化DS
         LEA BX,STR            ;取字符变量的偏移地址到BX
         MOV  CX,6              ;设置循环次数(6个字符)
LPP:     MOV AH,2               ;将功能号2送AH
         MOV  DL, [BX]          ;取一个要显示的字符到DL
                                ; 二号功能调用,显示一个字符
         INC  BX                ;修改指针
         INT  21H               ;调用中断21H
         LOOP  LPP              
         MOV  AH, 4CH          
INT  21H               ;返回DOS
CODE     ENDS
         END  START
;这段代码没有使用CX啊???
;LOOP与CX搭配使用,LOOP语句会使CX自动减一,如果CX=0,结束循环

例2: 在屏幕上显示欢迎字符串“Hello, World”。

DSEG SEGMENT
STRING   DB ‘Hello, World’,0DH, 0AH, $’  ;定义要显示的字符串
;0DH,0AH,结合使用,起到换行效果
;$是字符串结束的标志
DSEG  ENDS

CSEG  SEGMENT
    ASSUME CS:CSEG,DS:DSEG
START: MOV AX, DSEG
          MOV DS, AX                 ;初始化DS
          LEA DX ,STRING            ;获取要显示字串首地址
          MOV AH, 09H                ;调用字符串显示功能
                                     ;09H号功能显示字符串
          INT  21H                   ;调用中断21H
          MOV  AH, 4CH          
          INT  21H                             ;返回DOS
CSEG   ENDS
          END  START

例3  编写S=86H×34H-21H的程序,式中的3个数均为无符号数。

题目分析算:

(1)有3个数参加运算,所以要定义3个源操作数,因它们的类型相同,题目中没有要求分别存放,故只需定义一个字节类型变量来标识存放3个数的地址;

        86H,34H,21H都是8位

(2)还需要定义一个变量来存放运算结果,因运算中有乘法,故结果应为16位,因而存放结果的变量应定义为字类型的变量;

         注意乘法导致结果位数由8位变为16位。

(3)运算中要用到乘法指令,因3个操作数为无符号数,所以乘法指令用MUL。程序如下:

DATA SEGMENT               
NUM   DB 86H,34H,21H            ;定义源操作数
RESULT DW  ?                     ;定义结果存放单元        
DATA ENDS
CODE  SEGMENT
ASSUME CS: CODE, DS: DATA
START: MOV AX, DATA              ;初始化DS
MOV DS, AX
LEA SI,NUM                 ;NUM的偏移地址送SI 
LEA DI,RESULT              ;RESULT偏移地址送DI 
MOV AL, [SI]                ;AL86H
MOV BL, [SI+1]              ;BL34H
MUL BL                      ;AX86H×34H 
;MUL: AX=AL*BL
MOV BL, [SI+2]              ;BL21H
MOV BH, 0                   ;把高8位置为0
SUB AX, BX                  ;AX86H×34H-21H
MOV [DI], AX                ;结果送RESULT
MOV  AH, 4CH          
INT  21H                   ;返回DOS
	 CODE   ENDS
END  START

例4   两个多字节二进制数求和程序。

题目分析:

由于8088/8086CPU的内部寄存器均为16位。所以,在进行两个多字节数的求和运算时,一次只能完成一个字节或一个字的相加。低位字节(或字)相加的和可能会产生进位,那么在高位字节(或字)相加时则必须考虑该进位,否则就会使结果出错。因此,在多字节数求和运算中,要使用ADC指令,而不能使用ADD指令。

程序如下:

DATA  SEGMENT
BUFF1 DB 4FH, OB6H,7CH, 34H, 56H,  1FH      ;数1
;6个字节
BUFF2 DB 13H, 24H, 57H, 68H, OFDH, 9AH      ;数2
SUM   DB 6 DUP(?)                           ;和
CONT DB 3                                   ;数的字长为3
DATA  ENDS
CODE  SEGMENT
ASSUME CS: CODE, DS: DATA
START: MOV AX, DATA
MOV DS, AX
MOV SI,OFFSET BUFE1          ;SI指向数1
MOV DI, OFFSET BUFF2          ;DI指向数2
MOV BX, OFFSET SUM            ;BX指向存放和的单元
MOV CL, CONT                  ;共3个字,要做3次加法
MOV CH, O
CLC                          ;CF0(进位标志位)
COON:MOV AX, [SI]                  ;取数1的一个字
ADC AX, [DI]                  ;加上数2的相应字
ADD SI, 2                     ;修改指针
ADD DI, 2
MOV [BX], AX                  ;存本次加的结果
ADD BX, 2
LOOP GOON                     ;未加完,则循环(共循环3次)
MOV AH, 4CH
INT 21H                       ;返回Dos
CODE  ENDS
END START

例5:在当前数据段中DATA1开始的顺序80个单元中,存放着80位同学某门功课的考试成绩(0~100)。编写程序统计≥90分、80~89分、70~79分、60~69分以及<60分的人数,并将结果放到同一数据段的DATA2开始的5个单元中

题目分析

(1)这是一个具有多个分支的分支程序,结构如图1所示。需要将每一位学生的成绩依次与90、80、70、60进行比较,因是无符号数,所以用CF标志作为分支条件,相应指令为JC

(2)由于对每一位学生的成绩都要进行判断,所以需要用循环来处理,每次循环处理一个学生的成绩;

(3)因为无论成绩还是学生人数都不超过一个字节所能表示的数的范围,故所有定义的变量均为字节类型

(4)统计结果可用一个数组存放,元素0存放90分以上的人数,元素1存放80分以上的人数,元素2存放70分以上的人数,元素3存放60分以上的人数,元素4存放60分以下的人数

DATA SEGMENT
DATAI DB 80 DUP(?)           ;假定学生成绩已放入这80个单元中
DATA2 DB 5 DUP(0)            ;统计结果:≥90、80-89、70~79、60-69、<60
DATA ENDS
CODE SEGMENT
ASSUME CS: CODE, DS: DATA
START:  MOV AX, DATA
MOV DS, AX
MOV CX, 80               ;统计人数送CX
LEA SI, DATAI            ;SI指向学生成绩
LEA DI, DATA2            ;DI指向统计结果
AGAIN:  MOV AL, [SI]             ;取一个学生的成绩
CMP AL, 90               ;大于90分吗?
JC NEXT1                 ;若不大于,继续判断(跳转到NEXT1)
INC BYTE PTR[DI]         ;否则90分以上的人数加1
JMP STO                  ;转循环控制处理
NEXT1: CMP AL, 80               ;大于80分吗?
        JC NEXT2                 ;若不大于,继续判断
INC BYTE PTR[DI+1]       ;否则80分以上的人数加1
JMP STO                  ;转循环控制处理
NEXT2:  CMP AL, 70               ;大于70分吗
JC NEXT3                 ;若不大于,继续判断
INC BYTE PTR[DI+2]       ;否则70分以上的人数加1
JMP STO                  ;循环控制处理
NEXT3:  CMP AL, 60               ;大于60分吗?
JC NEXT4                 ;若不大于,继续判断
INC BYTE PTR[DI+3]       ;否则60分以上的人数加1
JMP STO                  ;转循环控制处理
NEXT4:  INC BYTE PTR[DI+4]       ; 60分以下的人数加1
STO:   INC SI                   ;指向下一个学生成绩
LOOP AGAIN               ;循环,直到所有成绩都统计完
MOV AH, 4CH
INT 21H                  ;返回DOS
CODE  ENDS
END START

例6:把从MEM单元开始的100个16位无符号数按从大到小的顺序排列。

题目分析:

(1)这是一个排序问题,由于是无符号数的比较,可以直接用比较指令CMP和条转移指令JNC来实现;

(2)这是一个双重循环程序,先使第一个数与下一个数比较,若大于则使其位置保持不变,小于则将大数放低地址,小数放高地址(即两数交换位置);

(3)以上完成了一次排序工作,再通过第二重的99次循环,即可实现对100个无符号数的大小排序。

(冒泡排序)

每次产生一个最小数放在最右边。

DSEG  MEMENG 
MEM  DW 100 DUP(?)   ;假定要排序的数已存人这100个字单元中
DSEG ENDS
CSEG  SEGMENT
ABGUME CS:CSEG, DS: DSEG
START:  MOV AX, DSEG
MOV DB, AX
LEA DI, MEM     ;DI指向待排序数的首址
MOV BL, 99      ;外循环只需99次即可
;外循环体从这里开始
NEXT1: MOV SI, DI      ;SI指向当前要比较的数
MOV CL, BL      ; CL为内循环计数器(不断减小)
;以下为内循环
NEXT2:  MOV AX,[SI]    ;取第一个数Ni
ADD SI, 2        ;指向下一个数Nj
CMP AX,[SI]     ;Ni≥Nj?
;CMP的功能相当于减法指令,只是对操作数之间运算比较
;不保存结果,对标志寄存器产生影响。
JNC NEXT3        ;若大于,则不交换
;JNC: jump if not carry:没有借位,即大于
MOV DX,[SI]     ;否则,交换Ni和Nj
MOV [SI-2], DX
MOV [SI], AX
NEXT3:  DEC CL            ;内循环结東?
JNZ NEXT2         ;若未结東,则继续
;JNZ:结果不为0则转移
;内循环到此结束
DEC BL             ;外循环结東? 
JNZ NEXT1;        ;若未结束,则继续
;外循环体结束
MOV AH, 4CH
INT   21H         ;返回DOS
CSEG   ENDS
END START

小感想:

现在大三了,从c到c++,到汇编, 甚至python,很多东西都学的浅尝辄止(学校授课)

大一大作业是用c写贪吃蛇,之后是银行管理系统,之后是学生成绩管理系统(带数据库)

感觉还是要自学,去看见漫无边际的程序世界。不是就是写各种语言的"hello world"。

有点可笑。

对于程序的思考:

逻辑+熟练使用各种语句,明白各种语句的含义。

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lpl还在学习的路上

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值