微机原理实验代码

实验一

判断字符串是否相等
编写程序,比较两个字符串STRING1和STRING2是否相同,若字符串相同则显示"Match!",否则显示"No Match!"
DATA SEGMENT        ;定义数据段
    STRING1 DB     'HAPPY ASM'    ;定义字符串1
    LEN     EQU  $-STRING1        ;定义常量LEN的值为字符串一的长度
    STRING2 DB   'HAPPY ASM'      ;定义字符串2
    MSG1    DB   'Match!', 0DH, 0AH, '$'    ;定义输出信息字符串
    MSG2    DB   'No match!', 0DH, 0AH, '$' ;定义输出信息字符串
DATA    ENDS        ;数据段定义结束 

CODE    SEGMENT            ;定义代码段
      ASSUME CS:CODE, DS:DATA, ES:DATA   ;关联段名与段寄存器
START:  MOV  AX, DATA      
        MOV  DS, AX        ;数据段段地址初始化
        MOV  ES, AX        ;附加段段地址初始化
      LEA  SI, STRING1   ;获取两个字符串的偏移地址
      LEA  DI, STRING2
      MOV  CX, LEN       ;将字符串长度写入计数寄存器

COMPARE:MOV  AL, [SI]  ;根据获取的偏移地址依次对比两个字符串的内容
      MOV  BL, [DI]
      CMP  AL, BL
      JNE  DISMATCH    ;根据对比结果跳转是否匹配
      
      INC  SI
      INC  DI          
LOOP  COMPARE    ;依次增加偏移地址并继续比较

MATCH:  LEA  DX, MSG1     ;若比较结束仍未跳转不匹配,说明相同
      JMP  DISP           ;跳转display显示输出
DISMATCH:LEA  DX, MSG2    ;若不匹配则将偏移地址送到DX数据寄存器
DISP: MOV   AH, 09H
      INT   21H            ;根据对比结果显示DX内容
      MOV   AH, 4CH
      INT   21H             ;结束
CODE ENDS
     END START

实验二

大小写转换
编写程序,从键盘输入一串字符,将其中的小写字母转变为大写字母,其他字符不作转换原样输出,结果在屏幕上显示
DATA SEGMENT   ;定义数据段
    SINPUT DB 0DH, 0AH, 'PLEASE INPUT A STRING:','$'  ;定义输入提示字符串
    SOUTPUT DB 0DH, 0AH, 'END:','$'       ;定义结束提示字符串
    
BUF DB 30               ;定义缓冲区,第一个字节为缓冲区的最大容量,可认为是入口参数
    DB ?                ;第二个字节为实际输入的字符数(不包括回车键),可看作出口参数
    DB 30 DUP(24H)      ;24H是 '$'    从第三个字节开始存放实际输入的字符串 
;若输入的字符数超过缓冲区的最大容量,则多出的部分被丢弃,系统并发出响铃,直到输入“回车”键才结束输入

DATA ENDS     ;数据段定义结束

CODE SEGMENT                ;定义代码段
     ASSUME CS:CODE, DS:DATA    ;关联段名与段寄存器
START:
    MOV AX, DATA       ;数据段段地址初始化(代码段不用初始化,会自动初始化)
    MOV DS, AX   
    
    MOV AH, 09H       
    LEA DX, SINPUT    
    INT 21H        ;使用DOS中断指令,显示输入提示字符串

    LEA DX, BUF
    MOV AH, 0AH    ;键盘缓冲输入中断指令,将从键盘输入的字符串存在BUF,回车结束
    INT 21H        

    MOV AH, 09H
    LEA DX, SOUTPUT
    INT 21H        ;使用DOS中断指令,显示结束提示字符串
    LEA SI, BUF+1     ;取字符串长度送至CL
    MOV CL, [SI]      
    MOV CH, 00H      ;将高位设为0,是为了接下来LOOP使用CX循环

    LEA SI, BUF+2     ;取第一个字符的地址
X2: MOV AL, [SI]      ;将第一个字符送至AL
    CMP AL, 0DH           ;是否为回车,是则跳转FINAL
    JE  FINAL
    CMP AL, 61H           ;小于'a',则跳转X1
    JB  X1
    CMP AL, 7AH           ;大于'z',则跳转X1
    JA  X1
    SUB AL, 20H       ;确定在a~z区间之后,进行加20H的操作转换为大写
X1: MOV [SI], AL      ;将字符从AL送回原缓存区
    INC SI            
    LOOP X2            ;偏移地址指针加一,继续比较
FINAL:
    LEA DX, BUF+2         ;取字符串首地址
    MOV AH, 09H          
    INT 21H                ;将转换后的字符串输出
    MOV AH, 4CH
    INT 21H
CODE ENDS
     END START 

实验三

子程序设计
利用子程序的方法编写程序,设有10个无符号数的字节序列,查找该序列中的最大值和最小值,并把结果在屏幕上显示
DATA SEGMENT
  ARRAY DB 4,5,9,12,12,10,9,5,7,8
  LEN DB $-ARRAY
  CRLF DB 0AH, 0DH, '$'
  STR1 DB 'THE MAX NUMBER IS:$'
  STR2 DB 'THE MIN NUMBER IS:$'
DATA ENDS

CODE SEGMENT
  ASSUME CS:CODE, DS:DATA
START:
  MOV AX, DATA
  MOV DS, AX
  
  CALL FIND            ;调用查找函数,找到最大值存入BH,最小值存入BL

  LEA DX, STR1
  MOV AH, 09H
  INT 21H                ;显示THE MAX NUMBER IS:

  MOV DL, BH
  CALL PRINTF           ;显示最大值

  LEA DX, CRLF
  MOV AH, 09H
  INT 21H                ;输出回车换行
  
  LEA DX, STR2
  MOV AH, 09H
  INT 21H                ;显示THE MIN NUMBER IS:
  
  MOV DL, BL
  CALL PRINTF            ;显示最小值

  MOV AH, 4CH            ;结束程序
  INT 21H

FIND PROC                ;定义查找函数
     MOV CL, LEN
     SUB CL, 1
     
     LEA SI, ARRAY
     MOV BH, [SI]        ;BH负责存大数
     MOV BL, [SI]        ;BL负责存小数
X:   INC SI
     MOV AL, [SI]        ;存下一个数
     CMP AL, BL
     JB MIN        ;无符号小于则跳转
     CMP AL, BH
     JBE  NEXT        ;无符号小于等于则跳转,此时也就是判断是否等于
     MOV BH, AL      ;排除小于和等于,只剩大于,将更大的AL存入BH
     JMP NEXT          
MIN: MOV BL, AL        ;将更小的AL存入BL
NEXT: LOOP X           ;继续比较下一个
     RET
FIND ENDP

PRINTF PROC           ;定义输出函数
     AND DL, 0FH      ;将DL高四位清零,低四位保留
     CMP DL, 9        
     JBE L1            ;如果DL小于等于9,则加30H转换输出
     ADD DL, 37H       ;否则加37H转换输出
;这里转换输出是因为调用的是02H功能,是单字符输出功能,而DL里面保存的是数值而非字符,需要转换为字符输出,也就是对应的ASCII码值,这样才能输出正确结果,否则会出现输出乱码,其中大于9的对应的是字母
     JMP NEXT1         ;跳转到NEXT1输出
L1:  ADD DL, 30H
NEXT1: MOV AH,02H
       INT 21H 
     RET
PRINTF ENDP            

CODE ENDS
END START

实验四

8259内部中断
用手动产生单脉冲作为中断请求信号,要求每按一次开关产生一次中断,在屏幕上显示一次"TPCA Interrupt!",中断十次后程序退出
DATA SEGMENT
    MESS DB 'TPCA INTERUPT!',0DH,0AH,'$'
DATA ENDS

CODE SEGMENT
     ASSUME CS:CODE, DS:DATA   
START:
     MOV AX, CS
     MOV DS, AX

     LEA DX, INT3       ;等效MOV DX, OFFSET INT3     

     MOV AX, 250BH      ;设置IRQ3的中断向量,设置完后,识别到有0BH的中断类型号,会根据DS:DX的中断向量执行相应的中断服务程序
     INT 21H            ;中断,输出

     IN  AL, 21H        ;从主片端口地址21H读入中断屏蔽器的当前屏蔽字  
     AND AL, 0F7H       ;取消屏蔽D3的中断,1111 0111      
     OUT 21H, AL        ;写回主片改变后的屏蔽字
     MOV CX, 10         ;设置中断循环次数为10次,由CX储存
     STI                ;Set Interupt,允许中断发生,恢复中断,设置中断标志位
STOP: JMP STOP          ;等待脉冲
INT3:                           
     MOV AX, DATA       ;将DATA数据段送入AX寄存器中暂存
     MOV DS, AX         ;将AX寄存器中的数据送入DS中

     LEA DX, MESS       ;取得MESS数据存储区的首地址并送入DX寄存器中
     MOV AH, 09H        ;调用DOS的9号功能,显示每次中断的提示信息       
     INT 21H            ;中断,输出中断提示信息

     MOV AL, 20H        ;从端口地址20H读入ISR内容送入AL   
     OUT 20H, AL        ;主片发出EOI结束命令
     LOOP NEXT          ;循环执行NEXT,直到中断程序的远返回

     IN  AL, 21H        ;从主片端口地址21H读入中断屏蔽器的当前屏蔽字
     OR  AL, 08H        ;屏蔽D3的中断,0000 1000         
     OUT 21H, AL        ;写回主片改变后的屏蔽字
     STI                ;恢复中断,设置中断标志位      
              
     MOV AH, 4CH        ;返回DOS
     INT 21H
NEXT: IRET              ;指令执行到中断程序的远返回
CODE ENDS
END START

连线图暂略

实验五

8255并行接口与交通灯控制
编写程序,模拟交通信号灯工作状态,利用实验台上的8255并行接口芯片的三个端口中的任意一端口,控制两组红、黄、绿六个发光二极管按照十字路口交通灯的规律交替亮、灭变化,当按下任意键则停止运行,并返回DOS
CODE SEGMENT
     ASSUME CS:CODE
START:
    MOV AL,80H            ;1000 0000控制字      
    MOV DX,28BH           ;段码地址
    OUT DX,AL             ;写入控制字
    
    MOV AL,00100100B      ;亮灯输出
    MOV DX,28AH        
    OUT DX,AL
    CALL LDELAY           ;调用长延时
    
   MOV CX,3
L1:MOV AL,01000100B       ;亮灯输出 
   MOV DX,28AH
   OUT DX,AL
   CALL SDELAY            ;调用短延时
   MOV AL,00000100B       ;亮灯输出
   MOV DX,28AH
   OUT DX,AL
   CALL SDELAY            ;调用短延时    
   LOOP L1                ;三次闪烁转到下一个亮灯模式
 
   MOV AL,10000001B       ;亮灯模式
   MOV DX,28AH
   OUT DX,AL
   CALL LDELAY            ;调用长延时
            
   MOV CX,3
L2:MOV AL,10000010B       ;以下同理
   MOV DX,28AH
   OUT DX,AL
   CALL SDELAY
   MOV AL,10000000B
   MOV DX,28AH
   OUT DX,AL
   CALL SDELAY
   LOOP L2

    MOV AH,01H            ;查询键盘缓冲区,对键盘扫描但不等待,并设置ZF标志
    INT 16H               ;若有按键操作(即键盘缓冲区不空),则ZF=0,AL中存放的是输入的ASCII码
    JZ START              ;AH中存放输入字符的扩展码。若无键按下,则标志位ZF=1,重复执行
                   
    MOV AH, 4CH
    INT 21H
    
LDELAY PROC               ;长延时子程序定义
    PUSH CX
    PUSH DI

    MOV CX,2000H
Y1: MOV DI,2000H
X1: DEC DI
    JNZ X1
    LOOP Y1
    POP DI
    POP CX
    RET
LDELAY ENDP

SDELAY PROC               ;短延时子程序定义
    PUSH CX
    PUSH DI
    MOV CX,500H
    Y2:MOV DI,1000H
    X2:DEC DI
    JNZ X2
    LOOP Y2
    POP DI
    POP CX
    RET
SDELAY ENDP

CODE ENDS
     END START

连线图暂略

实验六

8254可编程定时/计数器
编写程序,利用实验台上的8254定时器对1MHz的时钟脉冲进行分频,产生频率为1HZ的方波信号,并用逻辑笔(或示波器)观察
CODE SEGMENT
   ASSUME CS:CODE
START:
    MOV AL, 36H      ;0011 0110   
    MOV DX, 283H     ;设置计数器0-先读写低,再读写高-工作方式3-二进制
    OUT DX, AL
    
    MOV AX, 1000     ;设置计数初值
    MOV DX, 280H     ;将计数初值传入计数器0
    OUT DX, AL       ;先低位后高位
    MOV AL, AH
    OUT DX, AL
    
    MOV AL, 76H      ;0111 0110
    MOV DX, 283H     ;设置计数器1-先读写低,再读写高-工作方式3-二进制
    OUT DX, AL
    
    MOV AX, 1000     ;设置计数初值
    MOV DX, 281H     ;将计数初值传入计数器1
    OUT DX, AL       ;先低位后高位
    MOV AL, AH
    OUT DX, AL
    
    MOV AH, 4CH
    INT 21H
CODE ENDS
   END START 

连线图暂略

实验七

模/数(A/D)转换器
编写程序,从ADC0809通道采集电位器0~5V的直流电压,调节电位器,以改变模拟电压值,屏幕上不断地显示当前电压值A/D转换结果(用16进制数表示)
;电源接Y3(298H~29FH),IN0接电位器直流信号0~+5V. 

DATA SEGMENT
DATA ENDS
CODE SEGMENT
    ASSUME DS:DATA,CS:CODE
START:
    MOV AX,DATA 
    MOV DS,AX

BEG:
    MOV DX,298H
    OUT DX,AL          ;启动端口,无所谓AL里面的值
    MOV CX,0FFH        ;进行一个长延时DELAY
    LL:LOOP LL
                                                              
    MOV DX,298H
    IN AL,DX            ;读取端口的值到AL
    
    MOV BL,AL            ;获取AL高四位,并存入低四位
    SHR BL,4             ;SHR(右移)指令使目的操作数逻辑右移一位,最高位用 0 填充
                         ;最低位复制到进位标志位(CF),而进位标志位中原来的数值被丢弃
    MOV DL,BL            ;把高四位存DL
    CALL DISPLAY         ;调用子函数显示

    MOV BL,AL            ;同理低四位
    AND BL,0FH           ;0000 1111将高四位清零,保留低四位
    MOV DL,BL            ;把低四位存DL
    CALL DISPLAY         ;调用子函数显示

    MOV DL,0DH           ;将回车的ASCII码存入DL
    MOV AH,02H           ;输出回车
    INT 21H

    MOV DL,0AH           ;将换行的ASCII码存入DL
    MOV AH,02H           ;输出换行
    INT 21H

    MOV AH,01H           ;用来查询键盘缓冲区,对键盘扫描但不等待,并设置ZF标志。
    INT 16H              ;AL中存放的是输入的ASCII码,AH中存放输入字符的扩展码。
                         ;若有按键操作(即键盘缓冲区不空),则ZF=0,若无键按下,则标志位ZF=1。
    
    JZ BEG               ;无按键按下则持续执行扫描,有则退出

EXIT:
    MOV AH,4CH
    INT 21H

    MOV AH,01H           ;输入的字符就被存储在AL中
    INT 21H

DISPLAY PROC
    CMP DL,9             ;将数字值转换为对应十六进制字符的ASCII码值
    JBE ADD30
    ADD DL,07H
ADD30:
    ADD DL,30H
    MOV AH,02H           ;单字符输出
    INT 21H
    RET
DISPLAY ENDP

CODE ENDS
    END START
    

连线图暂略

  • 6
    点赞
  • 65
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
根据引用[1]提供的方法,可以使用汇编语言来统计字符串的总字符数、字母数、数字数和其他字符数。具体步骤如下: 1. 将字符串输入到数据段中。 2. 使用循环逐个取出字符串中的字符,并判断其类型。 3. 根据字符类型,将对应的计数器加1。 4. 循环结束后,输出各计数器的数值以及字符串的总长度。 下面是一个汇编语言的例子,可以实现上述功能: ```assembly DATA SEGMENT STR DB 'Hello, World!', '$' LEN DB ? CHAR_CNT DB ? LETTER_CNT DB ? DIGIT_CNT DB ? OTHER_CNT DB ? DATA ENDS CODE SEGMENT START: MOV AX, @DATA MOV DS, AX MOV CX, 0 ; 初始化计数器 MOV BX, 0 MOV DX, 0 MOV SI, 0 LOOP1: MOV AL, STR[SI] ; 取出一个字符 CMP AL, '$' ; 判断是否结束 JE END_LOOP1 INC CHAR_CNT ; 字符计数器加1 CMP AL, 'A' JB NOT_LETTER CMP AL, 'Z' JA NOT_LETTER INC LETTER_CNT ; 字母计数器加1 ADD AL, 32 ; 大写字母变小写字母 MOV STR[SI], AL ; 修改字符串 JMP CONTINUE_LOOP1 NOT_LETTER: CMP AL, '0' JB OTHER_CHAR CMP AL, '9' JA OTHER_CHAR INC DIGIT_CNT ; 数字计数器加1 JMP CONTINUE_LOOP1 OTHER_CHAR: INC OTHER_CNT ; 其他字符计数器加1 CONTINUE_LOOP1: INC SI ; 指针加1 JMP LOOP1 END_LOOP1: MOV LEN, CHAR_CNT ; 保存字符串总长度 ; 输出各计数器的数值 MOV AH, 02H MOV DL, LETTER_CNT ADD DL, 30H INT 21H MOV DL, ',' INT 21H MOV DL, DIGIT_CNT ADD DL, 30H INT 21H MOV DL, ',' INT 21H MOV DL, OTHER_CNT ADD DL, 30H INT 21H MOV DL, ',' INT 21H MOV DL, CHAR_CNT ADD DL, 30H INT 21H MOV AH, 4CH INT 21H CODE ENDS END START ``` 上述汇编程序可以统计字符串中的各种字符数,并将大写字母转换为小写字母。如果只需要统计大写字母的个数并将其转换为小写字母,可以根据引用提供的方法进行修改。具体步骤如下: 1. 将字符串输入到数据段中。 2. 使用循环逐个取出字符串中的字符,并判断其是否为大写字母。 3. 如果是大写字母,将计数器加1,并将其转换为小写字母。 4. 循环结束后,输出原字符串和修改后的字符串。 下面是一个汇编语言的例子,可以实现上述功能: ```assembly DATA SEGMENT STR DB 'Hello, World!', '$' COUNT DB ? DATA ENDS CODE SEGMENT START: MOV AX, @DATA MOV DS, AX MOV CX, 0 ; 初始化计数器 MOV SI, 0 LOOP1: MOV AL, STR[SI] ; 取出一个字符 CMP AL, '$' ; 判断是否结束 JE END_LOOP1 CMP AL, 'A' JB NOT_UPPER CMP AL, 'Z' JA NOT_UPPER INC CX ; 大写字母计数器加1 ADD AL, 32 ; 大写字母变小写字母 MOV STR[SI], AL ; 修改字符串 NOT_UPPER: INC SI ; 指针加1 JMP LOOP1 END_LOOP1: MOV COUNT, CX ; 保存大写字母的个数 ; 输出原字符串 MOV AH, 09H LEA DX, STR INT 21H ; 输出修改后的字符串 MOV AH, 09H LEA DX, STR INT 21H MOV AH, 4CH INT 21H CODE ENDS END START ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值