【汇编】求十进制数的补码并转二进制和十六进制输出

【汇编】求十进制数的补码并转二进制和十六进制输出

(多组输入输出,使用宏库文件)

代码如下,有详细注释

Include macro_lib.MAC
data segment
    string db 10,?,10 dup(?) ;用于存放输入的十进制数 这里十进制数在-32768~32767之间(16位有符号数)
    ;可以出现负数,此程序功能为用二进制和十六进制显示这个十进制数的补码
data ends

code segment
    assume cs:code ,ds:data



    ;输入多个十进制数,输入q字符(ascii码为113)结束程序
start:
    sta: inputs string ;调用宏指令库中的输入字符串
    crlf ;回车换行
    ;第一位有三种情况 
    ;1.0~9 转正数处理 ascii码为48~57
    ;2.'-' 转负数处理 ascii码为45
    ;3.'q' 退出 ascii码为113
    ;下面取第一位
    lea bx,string
    add bx,2
    mov cl,[bx] ;借助cl
    cmp cl,113
    JZ ex ;如果ZF=1,即输入为q则结束程序
    cmp cl,45
    JZ nega ;如果ZF=1,即输入为负数




;bx是string 的偏移地址
;正数,没有跳ex和nega 
posi:  
sub bx,2
mov cx,0
mov cl,[bx+1];cx存放实际串长
;cx+1指向串最后一位
mov ax,1;初始权值为1
mov bx,0;bx存放值
mov dx,10;常量
lp1:
push dx
mov dh,0;高位置0
push bx
mov bx,cx
mov dl,[bx+1];将当前位置的ascii码给dl,由于是数字为48~57
pop bx
sub dl,48;转为数值,dx为数字
push ax;保留当前权值
mul dx;数字乘以当前权值,结果低位在ax中,高位在dx中,即dx这里会被0覆盖(数比较小)
;但没关系,会pop,即只有ax的数值有用 
add bx,ax
pop ax
mov dx,10;
mul dx
pop dx ;dx再恢复10 此时ax权值已经在以前基础上*10了
loop lp1 ;loop进行前会对cx--,不为零则循环
;循环结束,bx为所求值,由于正数的补码是其本身,下面直接输出二进制和十六进制即可

;2进制
mov cx,16;循环16次
shift1:
rol bx,1
mov al,bl
and al,01h ;取最右1位
add al,30h  ;转为ascii码
putchar al  ;输出al中的ascii码对应的字符 0/1
loop shift1 ;循环16次后bx不变
put3space ;输出3个空格
;16进制
mov cx,4;循环4次
shift2:
rol bx,1
rol bx,1
rol bx,1
rol bx,1
mov al,bl
and al,0fh ;取最右四位
add al,30h  ;转为ascii码
cmp al,39h
jle dig1 ;是0~9 则转dig
add al,7 ;是A~F
dig1:   
putchar al  ;输出al中的ascii码对应的字符
loop shift2 ;循环4次后bx不变
;输出回车换行
crlf
jmp sta;再次输入




;负数
nega:
sub bx,2
mov cx,0
mov cl,[bx+1];cx存放实际串长
dec cx
;cx+2指向串最后一位
mov ax,1;初始权值为1
mov bx,0;bx存放值
mov dx,10;常量
lp2:
push dx
mov dh,0;高位置0
push bx
mov bx,cx
mov dl,[bx+2];将当前位置的ascii码给dl,由于是数字为48~57
pop bx
sub dl,48;转为数值,dx为数字
push ax;保留当前权值
mul dx;数字乘以当前权值,结果低位在ax中,高位在dx中,即dx这里会被0覆盖(数比较小)
;但没关系,会pop,即只有ax的数值有用 
add bx,ax
pop ax
mov dx,10;
mul dx
pop dx ;dx再恢复10 此时ax权值已经在以前基础上*10了
loop lp2 ;loop进行前会对cx--,不为零则循环
;循环结束,bx为所求值的正直,下面求其补码,并以二进制和十六进制输出
;由于是负数,所以其补码是各位取反 由于高位是0 所以也要取反 所以
;各位异或1
xor bx,0FFFFH
add bx,1
;现在bx为补码了,下面直接输出二进制和十六进制即可

;2进制
mov cx,16;循环16次
shift3:
rol bx,1
mov al,bl
and al,01h ;取最右1位
add al,30h  ;转为ascii码
putchar al  ;输出al中的ascii码对应的字符 0/1
loop shift3 ;循环16次后bx不变
put3space   ;输出3个空格
;16进制
mov cx,4;循环4次
shift4:
rol bx,1
rol bx,1
rol bx,1
rol bx,1
mov al,bl
and al,0fh ;取最右四位
add al,30h  ;转为ascii码
cmp al,39h
jle dig2 ;是0~9 则转dig
add al,7 ;是A~F
dig2:   
putchar al  ;输出al中的ascii码对应的字符
loop shift4 ;循环4次
;输出回车换行
crlf
jmp sta;再次输入

ex: mov ah,4ch
    int 21h
code ends
    end start

macro_lib.MAC

cr equ 13
lf equ 10
spa equ 32
getchar macro
        mov ah,1
        int 21h ;al为输入字符
        endm
putchar macro asc   
        mov ah,2
        mov dl,asc;输出dl上的字符
        int 21h
        endm
inputs  macro conbuf    
        mov ah,10
        mov dx,offset conbuf    ;ds:dx为缓冲区的首地址  其分别存放缓冲区大小(字节数)、实际填充数、串内容
        int 21h
        endm        
prints  macro msg
        mov ah,9
        mov dx,offset msg;  DS:DX为串地址,字符串应以'$'结尾
        int 21h
        endm
crlf    macro
        putchar cr ;回车19d  13H  
        putchar lf ;换行16d  10H
        endm

put3space macro
        putchar spa
        putchar spa
        putchar spa
        endm

exit    macro 
        mov ah,4ch
        int 21h
        endm

运行效果截图
《【汇编】求十进制数的补码并转二进制和十六进制输出》

    原文作者:进制转换
    原文地址: https://blog.csdn.net/Feynman1999/article/details/78845597
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞