原创 汇编实验三:各种数制显示

2010-12-21 15:51 2713 8 8 分类: 软件与OS

接下来的实验是利用汇编程序实现各种数制的显示其中有:4位BCD码,4位十六进制,8位二进制数。众所周知,在dos系统里面只能显示ASCII码,所以要显示这些数制码的话,就要将其转换成其对应的ASCCII码。下面我来讲一下,这些数字式如何转化的。


4位BCD码:4位BCD码,首先我们要不断的将4位数字都单独提取出来,其实利用一个循环就能实现,例如ax=1234h,al&0fh,就能将十位数屏蔽掉,安心的做我们转换工作,将这个数+30H就能变成ASCII码了。在然后将十位移至个位做同样的运算就可以了。


具体程序如下:


;-------------------------------
;实现4位的BCD码数显示
;-------------------------------
data segment   ;定义数据段
w dw 1234h          ;定义第1个加数
obuf db  10 dup(?)
data ends


stack segment para stack 'stack'   ;定义堆栈段
db 100 dup(?)
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 cl,4
      mov dx,w   ;将数组的数赋给dx
      mov si,4
      mov obuf[si],'$';将显示数据最后一位加上$结束符,字符串显示


ag:   mov al,0fh    ;
      and al,dl     ;取低2位的个位数
      add al,30h    ;调整为ASCII码
      dec si        ;指针减1
      mov obuf[si],al;将低2位的个位存进数据
      shr dx,cl     ;dx右移4个二进制,十位变成个位
      and dx,dx     ;当0&0时就不转移了
      jnz ag        ;jnz用法:上一个运算结果不等于或者不为0则转移
      mov dx,offset obuf ;转化完成,dx指针
      ;add dx,si          ;(DS:DX=指向字符串首址)
      mov ah,9
      int 21h
      ret       ;返回dos系统


start endp
code ends
     end start    ;程序结束


 


而16进制如何显示呢,其实实质上是差不多的,但是与4位BCD码不一样的就是当十六进制超过10后,要用abcdef来显示,所以这里需要调整:


将转换回来的数据+7处理


具体程序如下:


;-------------------------------
;实现4位的十六进制数显示
;-------------------------------
data segment   ;定义数据段
w dw 1223h          ;定义第1个加数
obuf db  10 dup(?)
data ends


stack segment para stack 'stack'   ;定义堆栈段
db 100 dup(?)
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 cx,404h ;cx=0404h
      mov dx,w    ;将数据载入
      mov si,4    ;si=4
      mov word ptr obuf[si],'$H'  ;在最后位加上$H用来结束
 ag:  mov al,0fh  ;取低位个位
      and al,dl   ;取个位
      add al,30h  ;将其变成ASCII码
      cmp al,3ah ;cmp比较指令  A>=B ,cf=0,JNC;;;A<B,cf=1,JC---意思是说假如是al小于3ah就不用调整+7,假如是3a的话就需要调整
      jc noad7    ;JC--进位位为1则转移
      add al,7    ;对大于39h的则需要调整 将数字+7
noad7: dec si     ;si-1
       mov obuf[si],al   ;将数据移如数组
       shr dx,cl         ;移4位去除个位,
       dec ch            ;ch=4,循环4次
       jnz ag            ;上面不为0就转移
       mov dx,offset obuf  ;将dx指向数据首地址
       mov ah,9            ;9号dos系统功能调用
       int 21h             ;


       ret       ;返回dos系统


start endp
code ends
     end start    ;程序结束


8位二进制的显示:


这里程序处理的就比较有味道。系统通过左移位的方法,将标志位CF读取移出的数字,再通过左循环移位的方法将CF值补给dl,再然后调用2号dos系统功能就可以完成显示一位,如斯循环8次就OK了。


具体程序如下:


;-------------------------------
;实现8位的二进制数显示
;-------------------------------
data segment   ;定义数据段
np db 0fh          ;定义第1个加数
obuf db  10 dup(?)
data ends


stack segment para stack 'stack'   ;定义堆栈段
db 100 dup(?)
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 ah,2  ;调用2号dos系统,单个字符显示
      mov cx,8  ;cx=8
  ag: mov dl,18h ;dl=18h
      shl np,1   ;shl是左移一位 00001111->00011110  cf=0  CF等于目标操作数最后移出的那一位
      rcl dl,1  ;RCL是带进位的循环左移指令,用原CF的值填补空出的位,移出的位再进入CF   dl=0  我明白了
      int 21h   ;
      loop ag   ;不断的循环8次,cx=8
      mov dl,'B'
      int 21h


      ret       ;返回dos系统


start endp
code ends
     end start    ;程序结束
通过本次实验,我终于搞清楚了,系统一般显示的是ASCII码,如何将其他的数值转换成ASCII码。感觉这些小细节最终会影响一个人继续走下去的能力,从汇编编程上面,我学习到了很多编程很基本的东西,算是复习我的编程了,希望再接再厉,加油。


 

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
8
关闭 站长推荐上一条 /3 下一条