SCAU 汇编实验三 将寄存器中的无符号数和有符号数以二进制、八进制、十六进制、十进制的形式输出

1.将BX中的无符号数以二进制的形式输出

;将bx中的无符号数以二进制的形式输出  
;关键:利用CF程序状态字配合ADC指令来判断ROL循环左移出的字符是0还是1
DATAS SEGMENT
    A DW 6C3BH  
DATAS ENDS

STACKS SEGMENT
    DB 100 DUP(?)
STACKS ENDS

CODES SEGMENT
    ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
    MOV AX,DATAS
    MOV DS,AX
    
    MOV CX,10H     ;循环16次
    MOV BX,A
L1: 
    ROL BX,1       ;温馨提醒,移位指令的后面那个操作数只能是CL或者1,切记
    
    MOV DL,30H     ;将数值转化ASCII码
    ADC DL,0       ;利用CF程序状态字来判断左移出的字符是0还是1
    
    MOV AH,2
    INT 21H
    LOOP L1

    MOV AH,4CH
    INT 21H
CODES ENDS
    END START

2.将BX中的无符号数以八进制的形式输出

;将bx中的无符号数以八进制的形式输出
;关键:16位二进制化成八进制,需要在16位二进制前面补两个零变成18位才能划分成刚好的6位八进制
;同时我们发现,如果不补零,6位八进制的最高位由于缺了高两位,所以转换后八进制的最高位只能是零或一
;所以一开始先单独将最高位移出,单独判断即可,余下的二进制数每三位循环左移来判断数值


DATAS SEGMENT
    A DW 6C3BH  
DATAS ENDS

STACKS SEGMENT
    DB 100 DUP(?)
STACKS ENDS

CODES SEGMENT
    ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
    MOV AX,DATAS
    MOV DS,AX
    
    MOV CH,5    ;十六位二进制化成八进制最多有16/3+1=6位,除开一开始单独处理的最高位,余下位循环5次即可
    MOV CL,3    ;CX寄存器不太够用,拆开两块来用,CL控制循环左移次数
                
                ;待会转16进制时再演示利用栈来重复使用cx的方法

    ROL A,1    ;先判断最高位
    MOV DX,A
    
    MOV DL,30H     
    ADC DL,0       ;利用CF程序状态字来判断左移出的字符是0还是1
    
    MOV AH,2
    INT 21H
    
L3:    
    ROL A,CL   ;将最高的三位循环左移,挪到最右边
    MOV BX,A
    AND BX,0007H;屏蔽前13位,只保留最后3位(AND 0000 0000 0000 0111)
    MOV DL,30H
    ADD DL,BL   ;BX不会太大,所以用BL无所谓了,转到dl然后输出
    MOV AH,2
    INT 21H

    DEC CH
    CMP CH,0
    JNZ L3

    MOV AH,4CH
    INT 21H
CODES ENDS
    END START

3.将BX中的无符号数以十六进制的形式输出

;将bx中的无符号数以十六进制的形式输出
;关键:①利用循环左移将最高的四位二进制数字输出(左移先输出最高位,可以省去栈)
      ; ②0-9和a-f的acsll码是有偏差的,所以需要分别判断所求的数字是在哪个区间,才能输出相应的字符)
      ;   0是30H,A是41H

DATAS SEGMENT
    A DW 6C3BH  
DATAS ENDS

STACKS SEGMENT
    DB 100 DUP(?)
STACKS ENDS

CODES SEGMENT
    ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
    MOV AX,DATAS
    MOV DS,AX
    
    MOV CX,4    ;十六进制最多有16/4=4位,循环4次即可
L1: PUSH CX     ;将循环次数的控制数入栈,待会loop前再pop出来即可,下面就能正常使用cl了
    MOV CL,4
    ROL A,CL   ;将最高的四位循环左移,挪到最右边
    MOV BX,A
    AND BX,0FH;屏蔽前12位,只保留最后4位
    CMP BX,9    ;判断数字是在哪个区间
    JA L2        ;如果bx大于9,去L2玩
    MOV DL,30H
    ADD DL,BL   ;输出
    MOV AH,2
    INT 21H
    POP CX
    LOOP L1
L2:
    MOV DL,37H   ;41H-A=37H
    ADD DL,BL   ;输出  
    MOV AH,2
    INT 21H
    POP CX
    LOOP L1

    MOV AH,4CH
    INT 21H
CODES ENDS
    END START

4.将BX中的无符号数以十进制的形式输出

;将bx中的无符号数以十进制的形式输出
;关键:正如我们在求某个数的二进制表示时,曾经会用到不断除以2取余数的方法
;     在汇编中求十进制表示也是同样的思路,将二进制数不断除以十取余数,商为零就停止

DATAS SEGMENT
    A DW  6C3BH 
    COUNT DW 0 
DATAS ENDS

STACKS SEGMENT
    DB 100 DUP(?)
STACKS ENDS

CODES SEGMENT
    ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
    MOV AX,DATAS
    MOV DS,AX
   
    MOV AX,A      
    MOV CX,10     ;待会一直除以10取余数,值得提醒的是,一个十六位二进制数除以10,
                  ;是不一定能放得进八位寄存器的,所以这里要使用cx来装载除数
                  ;使得待会机器自动以(DX,AX)/SRC->AX(商),DX(余数)的方式来运算
                  ;如果使用cl等寄存器,会提示divide error(除0错误)
    
L1: XOR DX,DX     ;务必记得,余数是有用到dx的,每次除法都务必先清空     
    DIV CX        ;除以10
    PUSH DX       ;余数入栈
    
    INC COUNT
    CMP AX,0      ;商为0就走
    JNE L1
    
L2:
    POP DX
    ADD DX,30H
    
    DEC COUNT
    CMP COUNT,0
    MOV AH,2      ;栈中数字pop输出即为最终答案
    INT 21H 
    JNE L2
   
    MOV AH,4CH
    INT 21H
CODES ENDS
    END START

5.将BX中的有符号数以十进制的形式输出

;将bx中的有符号数以十进制的形式输出,即输出范围为-32768到32767,思路很简单
;0-32767的输出方式沿用上面输出无符号数的代码,-32768到-1的代码输出时加个负号再减就okk
;而负数段='-'+(65536-被操作数)
;而汇编中提供了NEG指令来处理【65536-被操作数】这个操作,所以处理负数之前只要将被操作数neg一下就好了

DATAS SEGMENT
    A DW  65535

    COUNT DW 0 
    
DATAS ENDS

STACKS SEGMENT
    DB 100 DUP(?)
STACKS ENDS

CODES SEGMENT
    ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
    MOV AX,DATAS
    MOV DS,AX
   
    MOV AX,A    
    MOV CX,10   
    CMP AX,0     ; CMP AX,32767 这里要判断数是正数还是负数
    JL L2        ; JA L2        其实用有符号数比较转移指令,cmp数和0就行,小于0就是负数

    
L1: XOR DX,DX   ;判断为正数就循环执行L1,最后L5输出
    IDIV CX       
    PUSH DX    
    
    INC COUNT
    CMP AX,0
    JNE L1
    JMP L5
    
L2: NEG AX     ;判断为负数,则先求补,再进行和正数一毛一样的求十进制做法
L3: XOR DX,DX
      
    IDIV CX       
    PUSH DX    
    
    INC COUNT
    CMP AX,0
    JNE L3
    JMP L4


L4: MOV DL,'-'     ;如果判断为负数,输出数字前先输出一个负号
    MOV AH,2
    INT 21H   
L5:                ;从栈中倒序输出
    POP DX
    ADD DX,30H
    
    DEC COUNT
    CMP COUNT,0
    MOV AH,2
    INT 21H
    JNE L5
   
    MOV AH,4CH
    INT 21H
    
CODES ENDS
    END START

6.教材习题(代码段)P193

5.1 输入小写字母显示相应的大写字母

L1:
    MOV AH,7
    INT 21H
    
    CMP AL,'a'  ;输入合法性检查
    JB L1
    CMP AL,'z'
    JA L1
    
    MOV DL,AL
    SUB DL,20H
    MOV AH,2
    INT 21H

5.2 输入小写字母 顺序输出周围两个字符和它本身

L1:   
    MOV AH,7
    INT 21H
    MOV DL,AL
    
    CMP AL,'a'  
    JB L1
    CMP AL,'z'
    JA L1
    
    MOV CX,3
    DEC DL
L2: MOV AH,2
    INT 21H
    INC DL
    LOOP L2

5.3 将AX拆成四份,分别存放在AL,BL,CL,DL中

    MOV AX,0ABCDH
    MOV DX,AX        ;存个备份
    
    
    AND AX,0F000H 
    MOV CL,4
    ROL AX,CL
    
    MOV BX,DX
    AND BX,0F00H
    MOV CL,8
    SHR BX,CL
    
    MOV CX,DX
    AND CX,0F0H
    SHR CX,1      ;移位指令的CNT在8086里只能是1和CL,但是CL最后要存东西,那就简单粗暴一点
    SHR CX,1      
    SHR CX,1
    SHR CX,1
       
    AND DX,0FH

AX原内容:0ABCDH

结果:
在这里插入图片描述

  • 9
    点赞
  • 57
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值