接下来的实验是利用汇编程序实现各种数制的显示其中有: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码。感觉这些小细节最终会影响一个人继续走下去的能力,从汇编编程上面,我学习到了很多编程很基本的东西,算是复习我的编程了,希望再接再厉,加油。
文章评论(0条评论)
登录后参与讨论