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

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

题目:
输入: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的用法需要搞清楚
  • 14
    点赞
  • 75
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

海轰Pro

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值