汇编语言--输入两位十六进制数,输出其十进制值

举报
海轰Pro 发表于 2021/08/06 00:02:24 2021/08/06
【摘要】 输入两位十六进制数,输出其十进制值 题目: 输入:ff 输出:255 输入:12 输出:018 (默认字符为小写) 方法一 代码 stack segment stack ends data segment string_1 db 'please input a num: $' string_2 db 0ah,0dh,'the result is : $' ...

输入两位十六进制数,输出其十进制值

题目:
输入:ff
输出:255

输入:12
输出:018
(默认字符为小写)

方法一

代码

stack segment 
stack ends

data segment
string_1 db 'please input a num: $'
string_2 db 0ah,0dh,'the result is : $'
result db 0,0,0  ;30分别用来存储转换10进制后的值 因为最大为255 所以有三位  
data ends

code segment
assume cs:code,ds:data,ss:stack
start:

mov ax,data
mov ds,ax

;显示提示语句
lea dx,string_1
mov ah,09h
int 21h

;从键盘上读第一个字符
mov ah,01h
int 21h

;先减去30h 再判断是数字 还是a~f
sub al,30h

cmp al,10
jb shuzi ;是数字 跳转

;是字母a~f 则还要再减去27h
sub al,27h

mov cl,4
shl al,cl ;左移4位,相当于乘以16
mov bl,al
jmp in_2

 shuzi:
mov cl,4
shl al,cl
mov bl,al

;输入第二个字符
in_2:
mov ah,01h
int 21h

sub al,30h
cmp al,10
jb shuzi_2

sub al,27h
add bl,al
jmp change
shuzi_2:
add bl,al

;开始进制转换
change:
mov bh,0
mov ax,bx

mov bx,offset result+2
mov cx,3
mov si,10

;转换方法就是 循环除以10 得到每个位置的数 
;比如255 255%10=5 25%5=5 2%5=2 这样就把255分成了2 5 5do:
div si
mov [bx],dl
mov dx,0 ;因为除以的是si 16位的,所以被除数为32位,就是高16位为dx,低16位为ax,但dx会用来存余数,所以需要及时对dx清零
dec bx
mov ah,0
loop do
;显示结束语句
lea dx,string_2
mov ah,09h
int 21h mov bx,offset result
mov cx,3

shuchu:
mov dl,[bx]
add dl,30h
mov ah,02h
int 21h
inc bx
loop shuchu

mov ax,4c00h
int 21h

code ends
end start

  
 

结果
在这里插入图片描述
改进版

stack segment
db 10 dup(?)
stack ends

data segment
string_1 db 'please input a num: $'
string_2 db 0ah,0dh,'the result is: $'
result db 0,0,0
data ends

code segment
assume cs:code,ss:stack,ds:data
start:
mov ax,data
mov ds,ax

lea dx,string_1
mov ah,09h
int 21h

mov cx,2
xor bl,bl
input:
push cx
mov cl,4
mov ah,01h
int 21h
shl bl,cl
sub al,30h
cmp al,10
jb shuzi
sub al,27h
shuzi:
add bl,al
pop cx
loop input
mov bh,0
mov ax,bx

mov bl,10
mov cx,3
mov si,offset result+2

change:
div bl
mov [si],ah
dec si
mov ah,0
loop change

lea dx,string_2
mov ah,09h
int 21h

mov cx,3
mov si,offset result
output:
mov dl,[si]
add dl,30h
mov ah,02h
int 21h
inc si
loop output

mov ax,4c00h
int 21h

code ends
end start

  
 

方法二:

DATAS SEGMENT bin dw 10 dup(?) ;存放二进制结果 buf db 5 dup(?) ;存放十进制数 各个数位上的数值 如100,存放为 1,0,0 msg1 db 'please input a hex number',13,10,'$' msg2 db 'the dec number:',13,10,'$' crlf db 13,10,'$' ;回车换行
DATAS ENDS

stack segment
db 10 dup(?)
stack ends
CODES SEGMENT ASSUME CS:CODES,DS:DATAS
  mov cx,2

START:
push cx MOV AX,DATAS MOV DS,AX mov bx,0 ;初始化bx LEA dx,msg1 ;输出提示字符串 mov ah,9 int 21h input: mov ah,1 ;输入一个字符 int 21h sub al,30h ;把al中的ascii码转换成数值 jl init cmp al,10 ;输入的数在0-9之间跳转 jl toBin sub al,27h ;再转换为a-f cmp al,0ah ;输入的字符比a小 jl init ;结束输入 cmp al,10h ;输入的字符比f大 jge init ;结束输入 toBin: ;转换为二进制,把输入组合成意义上的数值 mov cl,4 shl bx,cl ;bx左移4位 mov ah,0 add bx,ax ;把输入后并从ascii码转换来的值与bx相加 mov bin,bx ;转换成二进制数后存到内存bin jmp input ;继续输入 init: ;初始化,准备转换 mov ax,bin mov bx,10 mov si,4 ;循环四次,最大到万位 toDec: ;转为各个数位上的数值,如100转换为1,0,0 百位为1... mov dx,0 div bx ;10法得到各个位上的数值 mov [buf+si],dl ;余数为该位上的值,第一次循环为个位,第二次为十位...;存到内存中 dec si cmp ax,0 ;商是否为0,为0算法结束 ja toDec lea dx,crlf ;显示提示 mov ah,9 int 21h lea dx,msg2 mov ah,9 int 21h output: ;输出内存中存放的各个数位上的数值 inc si mov dl,[buf+si] add dl,30h ;转为ascii mov ah,2 int 21h cmp si,4 jb output
mov cx,0
pop cx
 loop START MOV AH,4CH INT 21H
CODES ENDS END START

  
 

总结

  1. 计算机存储数据其实是以二进制数存储的,但是在debug模式下,我们看到的数都是以十六进制显示。
  2. 键盘输入其实存储的是对应的ASCII值,比如输入:f 其实存的是:66h
  3. 为了使输入:f 计算机存储的也是f,需要-57h 如果是数字的话,需要 -30h
  4. 这里是两位十六进制的数,输入一个字符后,在最后计算结果的时候,其实是第一个字符乘以16再加上第二个字符,在计算机中,乘以十六,相当于左移四位。所以在这里我的方法是:获得第一个字符后,左移四位,在与第二个字符进行相加。得到的就是我们需要的。
  5. 输出也是需要ASCII值,记得+30h
  6. div的用法需要搞清楚

文章来源: haihong.blog.csdn.net,作者:海轰Pro,版权归原作者所有,如需转载,请联系作者。

原文链接:haihong.blog.csdn.net/article/details/102379804

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。